sql >> Databáze >  >> RDS >> Mysql

Jak spravovat MySQL - pro Oracle DBA

Open source databáze se rychle stávají mainstreamem, takže migrace z proprietárních enginů na open source enginy je nyní jakýmsi trendem v oboru. Znamená to také, že my správci databází často musíme spravovat více databázových backendů.

V několika minulých příspěvcích na blogu jsme se s kolegou Paulem Namuagem zabývali několika aspekty migrace z Oracle na Percona, MariaDB a MySQL. Zřejmým cílem migrace je zprovoznit vaši aplikaci efektivněji v novém databázovém prostředí, je však zásadní zajistit, aby byli zaměstnanci připraveni ji podporovat.

Tento blog se zabývá základními operacemi MySQL s odkazem na podobné úkoly, které byste denně prováděli v prostředí Oracle. Poskytuje vám hluboký ponor do různých témat, abyste ušetřili čas, protože se můžete ztotožnit se znalostmi Oracle, které jste si již za ta léta vybudovali.

Budeme také mluvit o externích nástrojích příkazového řádku, které ve výchozí instalaci MySQL chybí, ale jsou potřebné k efektivnímu provádění každodenních operací. Verze s otevřeným zdrojovým kódem není dodávána s ekvivalentem například Oracle Cloud Control, takže pokud hledáte něco podobného, ​​podívejte se na ClusterControl.

V tomto blogu předpokládáme, že máte lepší znalosti Oracle než MySQL, a proto byste rádi znali vzájemný vztah mezi těmito dvěma. Příklady jsou založeny na platformě Linux, nicméně ve správě MySQL na Windows můžete najít mnoho podobností.

Jak se připojím k MySQL?

Začněme naši cestu velmi (zdánlivě) základním úkolem. Ve skutečnosti se jedná o druh úkolu, který může způsobit určitý zmatek kvůli odlišným konceptům přihlašování v Oracle a MySQL.

Ekvivalentem sqlplus / jako připojení sysdba je terminálový příkaz „mysql“ s příznakem -uroot. Ve světě MySQL se superuživatel nazývá root. Uživatelé databáze MySQL (včetně root) jsou definováni jménem a hostitelem, odkud se mohou připojit.

Informace o uživateli a hostitelích, odkud se může připojit, jsou uloženy v tabulce mysql.user. Při pokusu o připojení MySQL zkontroluje, zda klientský hostitel, uživatelské jméno a heslo odpovídají řádku v tabulce metadat.

Je to trochu jiný přístup než v Oracle, kde máme pouze uživatelské jméno a heslo, ale ti, kteří znají Oracle Connection Manager, mohou najít určité podobnosti.

Nenajdete zde předdefinované položky TNS jako v Oracle. Obvykle pro připojení správce potřebujeme uživatele, heslo a příznak hostitele -h. Výchozí port je 3306 (jako 1521 v Oracle), ale to se může lišit v různých nastaveních.

Ve výchozím nastavení bude mít mnoho instalací zablokované připojení root z jakéhokoli počítače ([email protected]’%’), takže se musíte přihlásit k serveru hostujícímu MySQL, obvykle přes ssh.

Zadejte následující:

mysql -u root

Pokud není nastaveno heslo root, stačí to. Pokud je vyžadováno heslo, měli byste přidat parametr -p.

mysql -u root -p

Nyní jste přihlášeni ke klientovi mysql (ekvivalent sqlplus) a zobrazí se výzva, obvykle 'mysql>'.

Je MySQL v provozu?

Chcete-li zjistit, zda je spuštěna, můžete použít spouštěcí skript služby mysql nebo příkaz mysqladmin. Poté můžete pomocí příkazu ps zjistit, zda jsou procesy mysql v provozu. Další alternativou může být mysqladmin, což je nástroj, který se používá k provádění administrativních operací.

mysqladmin -u root -p status

V Debianu:

/etc/init.d/mysql status

Pokud používáte RedHat nebo Fedoru, můžete použít následující skript:

service mysqld status

Nebo

/etc/init.d/mysqld status

Nebo

systemctl status mysql.service

V instancích MariaDB byste měli hledat název služby MariaDB.

systemctl status mariadb

Co je v této databázi?

Podobně jako v Oracle můžete dotazovat na objekty metadat a získat informace o databázových objektech.

Je běžné zde používat některé zkratky, příkazy, které vám pomohou vypsat objekty nebo získat DDL objektů.

show databases;
use database_name;
show tables;
show table status;
show index from table_name;
show create table table_name;

Podobně jako u Oracle můžete tabulku popsat:

desc table_name;

Kde jsou moje data uložena?

V MySQL neexistuje žádné vyhrazené interní úložiště jako ASM. Všechny datové soubory jsou umístěny v běžných přípojných bodech OS. Při výchozí instalaci můžete svá data najít v:

/var/lib/mysql

Umístění je založeno na proměnné datadir.

[email protected]:~# cat /etc/mysql/my.cnf | grep datadir
datadir=/var/lib/mysql

Uvidíte zde adresář pro každou databázi.

V závislosti na verzi a úložišti (ano, je jich zde několik) může adresář databáze obsahovat soubory ve formátu *.frm, které definují strukturu každé tabulky v databázi. U tabulek MyISAM jsou data (*.MYD) a indexy (*.MYI) také uloženy v tomto adresáři.

Tabulky InnoDB jsou uloženy v tabulkových prostorech InnoDB. Každý z nich se skládá z jednoho nebo více souborů, které jsou podobné tabulkovým prostorům Oracle. Ve výchozí instalaci jsou všechna data a indexy InnoDB pro všechny databáze na serveru MySQL uloženy v jednom tabulkovém prostoru, který se skládá z jednoho souboru:/var/lib/mysql/ibdata1. Ve většině nastavení nespravujete tabulkové prostory jako v Oracle. Nejlepším postupem je ponechat je se zapnutým automatickým rozšířením a maximální velikostí neomezenou.

[email protected]:~# cat /etc/mysql/my.cnf | grep innodb-data-file-path
innodb-data-file-path = ibdata1:100M:autoextend

InnoDB má log soubory, které jsou ekvivalentem Oracle redo logs, což umožňuje automatické zotavení po havárii. Ve výchozím nastavení existují dva soubory protokolu:/var/lib/mysql/ib_logfile0 a /var/lib/mysql/ib_logfile1. Data zpět jsou uložena v souboru tabulkového prostoru.

[email protected]:/var/lib/mysql# ls -rtla | grep logfile
-rw-rw----  1 mysql mysql  268435456 Dec 15 00:59 ib_logfile1
-rw-rw----  1 mysql mysql  268435456 Mar  6 11:45 ib_logfile0

Kde jsou informace o metadatech?

Neexistují žádné typy zobrazení dba_*, user_*, all_*, ale MySQL má interní zobrazení metadat.

Information_schema je definováno ve standardu SQL 2003 a je implementováno dalšími významnými databázemi, např. SQL Server, PostgreSQL.

Od MySQL 5.0 je k dispozici databáze information_schema obsahující informace z datového slovníku. Informace byly ve skutečnosti uloženy v externích souborech FRM. Konečně, po mnoha letech jsou soubory .frm pryč ve verzi 8.0. Metadata jsou stále viditelná v databázi information_schema, ale používají úložiště InnoDB.

Chcete-li vidět všechny skutečné pohledy obsažené v datovém slovníku v rámci klienta mysql, přepněte do databáze information_schema:

use information_schema;
show tables;

Další informace můžete najít v databázi MySQL, která obsahuje informace o db, události (úlohy MySQL), pluginech, replikaci, databázi, uživatelích atd.

Počet zobrazení závisí na verzi a dodavateli.

Vyberte * z v$session

Oracle select * from v$session je zde reprezentován příkazem SHOW PROCESSLIST, který zobrazí seznam vláken.

mysql> SHOW PROCESSLIST;
+---------+------------------+------------------+--------------------+---------+--------+--------------------+------------------+-----------+---------------+
| Id      | User             | Host             | db                 | Command | Time   | State              | Info             | Rows_sent | Rows_examined |
+---------+------------------+------------------+--------------------+---------+--------+--------------------+------------------+-----------+---------------+
|       1 | system user      |                  | NULL               | Sleep   | 469264 | wsrep aborter idle | NULL             |         0 |             0 |
|       2 | system user      |                  | NULL               | Sleep   | 469264 | NULL               | NULL             |         0 |             0 |
|       3 | system user      |                  | NULL               | Sleep   | 469257 | NULL               | NULL             |         0 |             0 |
|       4 | system user      |                  | NULL               | Sleep   | 469257 | NULL               | NULL             |         0 |             0 |
|       6 | system user      |                  | NULL               | Sleep   | 469257 | NULL               | NULL             |         0 |             0 |
|      16 | maxscale         | 10.0.3.168:5914  | NULL               | Sleep   |      5 |                    | NULL             |         4 |             4 |
|      59 | proxysql-monitor | 10.0.3.168:6650  | NULL               | Sleep   |      7 |                    | NULL             |         0 |             0 |
|      81 | proxysql-monitor | 10.0.3.78:62896  | NULL               | Sleep   |      6 |                    | NULL             |         0 |             0 |
|    1564 | proxysql-monitor | 10.0.3.78:25064  | NULL               | Sleep   |      3 |                    | NULL             |         0 |             0 |
| 1822418 | cmon             | 10.0.3.168:41202 | information_schema | Sleep   |      0 |                    | NULL             |         0 |             8 |
| 1822631 | cmon             | 10.0.3.168:43254 | information_schema | Sleep   |      4 |                    | NULL             |         1 |             1 |
| 1822646 | cmon             | 10.0.3.168:43408 | information_schema | Sleep   |      0 |                    | NULL             |       464 |           464 |
| 2773260 | backupuser       | localhost        | mysql              | Query   |      0 | init               | SHOW PROCESSLIST |         0 |             0 |
+---------+------------------+------------------+--------------------+---------+--------+--------------------+------------------+-----------+---------------+


13 rows in set (0.00 sec)

Je založen na informacích uložených v zobrazení information_schema.processlist. Pohled vyžaduje oprávnění PROCESS. Může vám také pomoci zkontrolovat, zda vám nedochází maximální počet procesů.

Kde je protokol výstrah?

Protokol chyb lze nalézt v my.cnf nebo pomocí příkazu show variables.

mysql> show variables like 'log_error';
+---------------+--------------------------+
| Variable_name | Value                    |
+---------------+--------------------------+
| log_error     | /var/lib/mysql/error.log |
+---------------+--------------------------+
1 row in set (0.00 sec)

Kde je seznam uživatelů a jejich oprávnění?

Informace o uživatelích jsou uloženy v tabulce mysql.user, zatímco granty jsou uloženy na několika místech, včetně mysql.user, mysql.tables_priv,

Uživatelský přístup k MySQL je definován v:

mysql.columns_priv, mysql.tables_priv, mysql.db,mysql.user

Nejvhodnějším způsobem, jak vypsat granty, je použít pt-grants, nástroj z Percona toolkit (nezbytný pro každý MySQL DBA).

pt-show-grants --host localhost --user root --ask-pass

Případně můžete použít následující dotaz (vytvořil Calvaldo)

SELECT
    CONCAT("`",gcl.Db,"`") AS 'Database(s) Affected',
    CONCAT("`",gcl.Table_name,"`") AS 'Table(s) Affected',
    gcl.User AS 'User-Account(s) Affected',
    IF(gcl.Host='%','ALL',gcl.Host) AS 'Remote-IP(s) Affected',
    CONCAT("GRANT ",UPPER(gcl.Column_priv)," (",GROUP_CONCAT(gcl.Column_name),") ",
                 "ON `",gcl.Db,"`.`",gcl.Table_name,"` ",
                 "TO '",gcl.User,"'@'",gcl.Host,"';") AS 'GRANT Statement (Reconstructed)'
FROM mysql.columns_priv gcl
GROUP BY CONCAT(gcl.Db,gcl.Table_name,gcl.User,gcl.Host)
/* SELECT * FROM mysql.columns_priv */

UNION

/* [Database.Table]-Specific Grants */
SELECT
    CONCAT("`",gtb.Db,"`") AS 'Database(s) Affected',
    CONCAT("`",gtb.Table_name,"`") AS 'Table(s) Affected',
    gtb.User AS 'User-Account(s) Affected',
    IF(gtb.Host='%','ALL',gtb.Host) AS 'Remote-IP(s) Affected',
    CONCAT(
        "GRANT ",UPPER(gtb.Table_priv)," ",
        "ON `",gtb.Db,"`.`",gtb.Table_name,"` ",
        "TO '",gtb.User,"'@'",gtb.Host,"';"
    ) AS 'GRANT Statement (Reconstructed)'
FROM mysql.tables_priv gtb
WHERE gtb.Table_priv!=''
/* SELECT * FROM mysql.tables_priv */

UNION

/* Database-Specific Grants */
SELECT
    CONCAT("`",gdb.Db,"`") AS 'Database(s) Affected',
    "ALL" AS 'Table(s) Affected',
    gdb.User AS 'User-Account(s) Affected',
    IF(gdb.Host='%','ALL',gdb.Host) AS 'Remote-IP(s) Affected',
    CONCAT(
        'GRANT ',
        CONCAT_WS(',',
            IF(gdb.Select_priv='Y','SELECT',NULL),
            IF(gdb.Insert_priv='Y','INSERT',NULL),
            IF(gdb.Update_priv='Y','UPDATE',NULL),
            IF(gdb.Delete_priv='Y','DELETE',NULL),
            IF(gdb.Create_priv='Y','CREATE',NULL),
            IF(gdb.Drop_priv='Y','DROP',NULL),
            IF(gdb.Grant_priv='Y','GRANT',NULL),
            IF(gdb.References_priv='Y','REFERENCES',NULL),
            IF(gdb.Index_priv='Y','INDEX',NULL),
            IF(gdb.Alter_priv='Y','ALTER',NULL),
            IF(gdb.Create_tmp_table_priv='Y','CREATE TEMPORARY TABLES',NULL),
            IF(gdb.Lock_tables_priv='Y','LOCK TABLES',NULL),
            IF(gdb.Create_view_priv='Y','CREATE VIEW',NULL),
            IF(gdb.Show_view_priv='Y','SHOW VIEW',NULL),
            IF(gdb.Create_routine_priv='Y','CREATE ROUTINE',NULL),
            IF(gdb.Alter_routine_priv='Y','ALTER ROUTINE',NULL),
            IF(gdb.Execute_priv='Y','EXECUTE',NULL),
            IF(gdb.Event_priv='Y','EVENT',NULL),
            IF(gdb.Trigger_priv='Y','TRIGGER',NULL)
        ),
        " ON `",gdb.Db,"`.* TO '",gdb.User,"'@'",gdb.Host,"';"
    ) AS 'GRANT Statement (Reconstructed)'
FROM mysql.db gdb
WHERE gdb.Db != ''
/* SELECT * FROM mysql.db */

UNION

/* User-Specific Grants */
SELECT
    "ALL" AS 'Database(s) Affected',
    "ALL" AS 'Table(s) Affected',
    gus.User AS 'User-Account(s) Affected',
    IF(gus.Host='%','ALL',gus.Host) AS 'Remote-IP(s) Affected',
    CONCAT(
        "GRANT ",
        IF((gus.Select_priv='N')&(gus.Insert_priv='N')&(gus.Update_priv='N')&(gus.Delete_priv='N')&(gus.Create_priv='N')&(gus.Drop_priv='N')&(gus.Reload_priv='N')&(gus.Shutdown_priv='N')&(gus.Process_priv='N')&(gus.File_priv='N')&(gus.References_priv='N')&(gus.Index_priv='N')&(gus.Alter_priv='N')&(gus.Show_db_priv='N')&(gus.Super_priv='N')&(gus.Create_tmp_table_priv='N')&(gus.Lock_tables_priv='N')&(gus.Execute_priv='N')&(gus.Repl_slave_priv='N')&(gus.Repl_client_priv='N')&(gus.Create_view_priv='N')&(gus.Show_view_priv='N')&(gus.Create_routine_priv='N')&(gus.Alter_routine_priv='N')&(gus.Create_user_priv='N')&(gus.Event_priv='N')&(gus.Trigger_priv='N')&(gus.Create_tablespace_priv='N')&(gus.Grant_priv='N'),
            "USAGE",
            IF((gus.Select_priv='Y')&(gus.Insert_priv='Y')&(gus.Update_priv='Y')&(gus.Delete_priv='Y')&(gus.Create_priv='Y')&(gus.Drop_priv='Y')&(gus.Reload_priv='Y')&(gus.Shutdown_priv='Y')&(gus.Process_priv='Y')&(gus.File_priv='Y')&(gus.References_priv='Y')&(gus.Index_priv='Y')&(gus.Alter_priv='Y')&(gus.Show_db_priv='Y')&(gus.Super_priv='Y')&(gus.Create_tmp_table_priv='Y')&(gus.Lock_tables_priv='Y')&(gus.Execute_priv='Y')&(gus.Repl_slave_priv='Y')&(gus.Repl_client_priv='Y')&(gus.Create_view_priv='Y')&(gus.Show_view_priv='Y')&(gus.Create_routine_priv='Y')&(gus.Alter_routine_priv='Y')&(gus.Create_user_priv='Y')&(gus.Event_priv='Y')&(gus.Trigger_priv='Y')&(gus.Create_tablespace_priv='Y')&(gus.Grant_priv='Y'),
                "ALL PRIVILEGES",
                CONCAT_WS(',',
                    IF(gus.Select_priv='Y','SELECT',NULL),
                    IF(gus.Insert_priv='Y','INSERT',NULL),
                    IF(gus.Update_priv='Y','UPDATE',NULL),
                    IF(gus.Delete_priv='Y','DELETE',NULL),
                    IF(gus.Create_priv='Y','CREATE',NULL),
                    IF(gus.Drop_priv='Y','DROP',NULL),
                    IF(gus.Reload_priv='Y','RELOAD',NULL),
                    IF(gus.Shutdown_priv='Y','SHUTDOWN',NULL),
                    IF(gus.Process_priv='Y','PROCESS',NULL),
                    IF(gus.File_priv='Y','FILE',NULL),
                    IF(gus.References_priv='Y','REFERENCES',NULL),
                    IF(gus.Index_priv='Y','INDEX',NULL),
                    IF(gus.Alter_priv='Y','ALTER',NULL),
                    IF(gus.Show_db_priv='Y','SHOW DATABASES',NULL),
                    IF(gus.Super_priv='Y','SUPER',NULL),
                    IF(gus.Create_tmp_table_priv='Y','CREATE TEMPORARY TABLES',NULL),
                    IF(gus.Lock_tables_priv='Y','LOCK TABLES',NULL),
                    IF(gus.Execute_priv='Y','EXECUTE',NULL),
                    IF(gus.Repl_slave_priv='Y','REPLICATION SLAVE',NULL),
                    IF(gus.Repl_client_priv='Y','REPLICATION CLIENT',NULL),
                    IF(gus.Create_view_priv='Y','CREATE VIEW',NULL),
                    IF(gus.Show_view_priv='Y','SHOW VIEW',NULL),
                    IF(gus.Create_routine_priv='Y','CREATE ROUTINE',NULL),
                    IF(gus.Alter_routine_priv='Y','ALTER ROUTINE',NULL),
                    IF(gus.Create_user_priv='Y','CREATE USER',NULL),
                    IF(gus.Event_priv='Y','EVENT',NULL),
                    IF(gus.Trigger_priv='Y','TRIGGER',NULL),
                    IF(gus.Create_tablespace_priv='Y','CREATE TABLESPACE',NULL)
                )
            )
        ),
        " ON *.* TO '",gus.User,"'@'",gus.Host,"' REQUIRE ",
        CASE gus.ssl_type
            WHEN 'ANY' THEN
                "SSL "
            WHEN 'X509' THEN
                "X509 "
            WHEN 'SPECIFIED' THEN
                CONCAT_WS("AND ",
                    IF((LENGTH(gus.ssl_cipher)>0),CONCAT("CIPHER '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL),
                    IF((LENGTH(gus.x509_issuer)>0),CONCAT("ISSUER '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL),
                    IF((LENGTH(gus.x509_subject)>0),CONCAT("SUBJECT '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL)
                )
            ELSE "NONE "
        END,
        "WITH ",
        IF(gus.Grant_priv='Y',"GRANT OPTION ",""),
        "MAX_QUERIES_PER_HOUR ",gus.max_questions," ",
        "MAX_CONNECTIONS_PER_HOUR ",gus.max_connections," ",
        "MAX_UPDATES_PER_HOUR ",gus.max_updates," ",
        "MAX_USER_CONNECTIONS ",gus.max_user_connections,
        ";"
    ) AS 'GRANT Statement (Reconstructed)'
FROM mysql.user gus;

Jak vytvořit uživatele mysql

Postup ‚vytvoření uživatele‘ je podobný jako u Oracle. Nejjednodušší příklad by mohl být:

CREATE user 'username'@'hostname' identified by 'password';
GRANT privilege_name on *.* TO 'username'@'hostname';

Možnost udělit a vytvořit v jednom řádku pomocí:

GRANT privilege_name  ON *.* TO 'username'@'hostname' identified by 'password';

byl odstraněn v MySQL 8.0.

Jak spustím a zastavím MySQL?

Pomocí této služby můžete zastavit a spustit MySQL.

Skutečný příkaz závisí na distribuci Linuxu a názvu služby.

Níže naleznete příklad s názvem služby mysqld.

Ubuntu

/etc/init.d/mysqld start 
/etc/init.d/mysqld stop 
/etc/init.d/mysqld restart

RedHat/Centos

service mysqld start 
service mysqld stop 
service mysqld restart
systemctl start mysqld.service
systemctl stop mysqld.service
systemctl restart mysqld.service

Kde jsou data konfigurace serveru MySQL?

Konfigurace je uložena v souboru my.cnf.

Do verze 8.0 vyžadovala jakákoli dynamická změna nastavení, která by měla zůstat po restartu, ruční aktualizaci souboru my.cnf. Podobně jako u Oracle scope=both můžete hodnoty změnit pomocí trvalé možnosti.

mysql> SET PERSIST max_connections = 1000;
mysql> SET @@PERSIST.max_connections = 1000;

Pro starší verze použijte:

mysql> SET GLOBAL max_connections = 1000;
$ vi /etc/mysql/my.cnf
SET GLOBAL max_connections = 1000;

Jak zálohuji MySQL?

Existují dva způsoby, jak provést zálohu mysql.

Pro menší databáze nebo menší selektivní zálohy můžete použít příkaz mysqldump.

Záloha databáze pomocí mysqldump (logická záloha):

mysqldump -uuser -p --databases db_name --routines --events --single-transaction | gzip > db_name_backup.sql.gz

xtrabackup, mariabackup (horká binární záloha)

Upřednostňovanou metodou je použití xtrabackup nebo mariabackup, externích nástrojů pro spouštění horkých binárních záloh.

Oracle nabízí horké binární zálohování v placené verzi s názvem MySQL Enterprise Edition.

mariabackup --user=root --password=PASSWORD --backup --target-dir=/u01/backups/

Streamujte zálohování na jiný server

Spusťte posluchač na externím serveru na preferovaném portu (v tomto příkladu 1984)

nc -l 1984 | pigz -cd - | pv | xbstream -x -C /u01/backups

Spusťte zálohování a přeneste na externí hostitel

innobackupex --user=root --password=PASSWORD --stream=xbstream /var/tmp | pigz  | pv | nc external_host.com 1984

Kopírovat oprávnění uživatele

Často je potřeba zkopírovat uživatelská oprávnění a přenést je na jiné servery.

Doporučený způsob, jak toho dosáhnout, je použít pt-show-grants.

pt-show-grants > /u01/backups

Jak obnovím MySQL?

Obnovení logické zálohy

MySQLdump vytvoří soubor SQL, který lze spustit pomocí příkazu source.

Chcete-li zachovat soubor protokolu provádění, použijte příkaz tee.

mysql> tee dump.log
mysql> source mysqldump.sql

Obnovení binární zálohy (xtrabackup/mariabackup)

Chcete-li obnovit MySQL z binární zálohy, musíte nejprve obnovit soubory a poté použít soubory protokolu.

Tento proces můžete porovnat s obnovou a obnovou v Oracle.

xtrabackup --copy-back --target-dir=/var/lib/data
innobackupex --apply-log --use-memory=[values in MB or GB] /var/lib/data

Doufejme, že tyto tipy poskytují dobrý přehled o tom, jak provádět základní administrativní úkoly.


  1. Vytvořit spouštěč pro protokolování SQL ovlivněné tabulky?

  2. Standardní číselné formátovací řetězce Podporované FORMAT() v SQL Server

  3. Filtr měsíce a roku CriteriaQuery

  4. Úvod do údržby záznamů