备份和导出MySQL数据库
- 2024-10-28 21:27:09
- 丁国栋
- 原创 68
mysqldump 的功能:
mysqldump的常用参数或组合:--skip-lock-tables --single-transaction --quick --routines --events --triggers --no-tablespaces
其他常用参数:
--master-data=2 --all-databases
常用于做主从同步
关于锁表
背景知识:在MySQL服务端执行FLUSH TABLES WITH READ LOCK;
,数据库里所有的库、表都将变为只读,此时如果执行UPDATE语句,会被阻塞,查看 processlist 可以查看到State
列显示 Waiting for global read lock
。执行 unlock tables;
移除这个锁定,其他等待执行的SQL会逐个执行。
mysqldump 执行过程中,有一个概念global read lock
(全局读锁) 需要清楚,全局读锁的本质也是 FLUSH TABLES WITH READ LOCK;
。
参见原文:This backup acquires a global read lock on all tables (using FLUSH TABLES WITH READ LOCK
) at
the beginning of the dump. As soon as this lock has been
acquired, the binary log coordinates are read and the lock is
released. If long updating statements are running when the FLUSH
statement is issued, the
MySQL server may get stalled until those statements finish.
After that, the dump becomes lock free and does not disturb
reads and writes on the tables. If the update statements that
the MySQL server receives are short (in terms of execution
time), the initial lock period should not be noticeable, even
with many updates.
添加全局读锁有以下几个参数中的1个:
--lock-all-tables
使用mysqldump时可能会在进程列表中出现 waiting for backup lock 状态的进程。
提示:MySQL主从服务器的版本最好是同一个版本,比如都是MySQL8.1 或都是MariaDB10.3.39。
提示:MySQL主从服务器最好在同一个网络下,这样复制数据会比较快,否则可能产生较高的复制延迟。
注意:如果是往已经配置了复制的从服务器里导入MySQL数据库数据,需要在导入之前停止复制进程,否则可能会遇到表锁导致无法写入,虽然可以在此时停止slave进程,但建议提前处理。
提示:使用mysqlbinlog
命令可以读取二进制日志文件的position
,如果在执行 mysqlbinlog
命令时提示 mysqlbinlog: unknown variable 'default-character-set=utf8mb4'
,可以使用mysqlbinlog
命令参数--no-defaults
,来忽略MySQL配置文件的配置。
在配置主从时需要跳过某个错误,可以这样操作:
STOP SLAVE; SET GLOBAL sql_slave_skip_counter = 1; START SLAVE; show slave status\G
在从服务器的my.cnf 配置文件中可以添加 slave-skip-errors = 1032,1062,1805
来实现忽略错误。
1032: Can't find record in 'table' 表示在执行某个操作时,无法找到指定的记录,通常发生在更新或删除操作时。
1062: Duplicate entry 'value' for key 'key_name' 违反唯一键约束,试图插入的值已经存在于表中。
1805: Count of rows is too large 数据表的行数超过了某个限制有关,可能是因为表的设计或配置问题。
一些操作提示:
- 在使用 mysqldump 命令导出时,建议与 gzip 进行组合使用,可以加快导出速度,因为“流+压缩”的速度通常大于磁盘的写入速度。mysqldump DATABASE | gzip > DATABASE.gz
- 如果需要把 SQL 导出为 CSV,可以执行
SELECT * INTO OUTFILE '/path/to/file.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' CHARACTER SET utf8mb4 FROM TABLE_NAME;
,注意有的数据库不支持CHARACTER SET utf8mb4
子句