数据库很重要,没有备份,数据丢失只能跑路。所以还是做好备份吧!
mysqldump是mysql自带的逻辑备份工具。
它的备份原理是,通过协议连接到mysql数据库,将需要备份的数据查询出来,将查询出的数据转换成对应的insert语句,当我们需要还原这些数据时,只要执行这些insert语句,即可将对应的数据还原。
备份对象 | 权限 |
---|---|
table | SELECT |
view | SHOW VIEW |
trigger | TRIGGER |
event | EVENT |
储存过程、函数 | SELECT mysql.proc |
转储用户 | SELECT "mysql"系统库 |
备份未使用–single-transaction选项时,还需要LOCK TABLES权限
mysqldump转储时默认不会备份INFORMATION_SCHEMA, performance_schema, sys,如有需求转储,需要再命令行上显式的指定他们。
mysqldump不会转储InnoDB CREATE TABLESPACE语句。
mysqldump不会备份 NDB cluster ndbinfo信息数据库。
在启用了GTID的数据库中使用mysqldump备份时需要注意,如果备份文件中包含了GTID信息,则无法恢复到没有启用GTID的数据库中。
Windows通过PowerShell使用如下命令进行转储时,转储文件默认使用UTF-16编码,而MySQL不允许将UTF-16作为连接字符集,所以通过如下命令备份的转储文件将无法正确加载到数据库中
mysqldump [options] > dump.sql
mysqldump是单线程,当数据量大时备份时间长,甚至有可能在备份过程中非事务表长期锁表对业务造成影响(SQL形式的备份数据恢复时间也较长)。
慎用 --compact 参数,此参数会去掉文件头与文件尾的一些参数设置(比如时区,字符集…),导致隐患。
参数 --lock-all-tables,–flush-privileges分别会在备份时进行 flush tables 和 flush privileges 操作,会产生GTID,备份从库时请注意。
在对数据库进行完全备份前,需要收集数据库相关信息(存储引擎、字符集等),确保备份内容完整,以下为收集语句:
-- 查看表相关信息
select table_schema,table_name,table_collation,engine,table_rows
from information_schema.tables
where table_schema NOT IN ('information_schema' , 'sys', 'mysql', 'performance_schema');-- 查看是否存在存储过程、触发器、调度事件等
select count(*) from information_schema.events;
select count(*) from utines;
select count(*) from iggers;-- 查看字符集信息
show variables like 'character%';
mysqldump的一些选项跟mysqlpump有些变化,在使用中需注意:
mysqldump | mysqlpump |
---|---|
–routines、–events的别名分别为-R、-E | –routines、–events不存在别名 |
存在master-data选项 | 不存在master-data选项,在进行构建主从需要通过master_auto_position来控制,不能够直观的通过指定binlog以及position来构建主从 |
-d的别名是–no-data | -d的别名是–skip-dump-rows |
转储文件默认带DROP TABLE语句 | 转储文件默认不带DROP TABLE、DROP USER(在使用–users备份用户时)语句,导入时可能会因为用户存在或者表存在而报错 |
备份不指定数据库或者-A会提示报错 | 备份不指定数据库或者-A,默认备份所有的数据。ps:除了INFORMATION_SCHEMA, performance_schema, ndbinfo, or sys |
MySQL5.7.7至今(2020/11/02)的所有5.7的小版本,在使用mysqldump在执行–all-databases都会清空mysql.proc导致sys无法正常使用。
mysql> SELECT * FROM sys.processlist;
ERROR 1356 (HY000): View 'sys.processlist' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
在使用mysqldump在执行–all-databases不会备份mysql.proc下的系统自身的存储过程,导致导入到新机器后,部分sys下的视图没法正常使用;这是一个BUG,并且只存在于MySQL5.7。
bug连接:
.php?id=86807
.php?id=92631
.php?id=83259
如果因为使用–all-databases参数已经造成sys异常报错,这样做可以修复其异常:
mysql_upgrade --upgrade-system-tables --skip-verbose --force-- 使用mysql_upgrade的时候要加上 --upgrade-system-tables。不然会扫描用户库表,期间加锁且速度一般。
如果你正在做一个大表 DDL 或者批量执行一个 sql 文件,执行一半远程连接断开了,你会不会想吐血?如果刚好执行批量 sql 时没有开启事务,想想后果会怎样?
使用 screen 时,即使当前远程终端被断开连接,也不会中断正在执行的任务:
## 安装 screen
yum install -y screen## 开启一个 screen
screen## 查看所有开启的 screen
screen -ls## 重新连接到指定的 screen
screen -r xxx
参数 | 原因 |
---|---|
lock_wait_timeout | 默认值为1年,如果没有修改默认设置,或者当前值是个挺长的时间,当mysqldump遇到长事务并在获取lock超时时,mysqldump不会退出,会等待获取MDL锁。此时界面无任何输出,使用者不进入数据库查看,不会感知备份停滞等待,影响备份工作进度 |
检查mysqldump备份角色,注意如果在从库使用下面mysqldump命令时,不要将–master-data和–flush-logs一起使用,有可能造成数据库死锁影响备份与复制。
注意不仅需要备份数据,还需要备份存储过程、触发器、事件:
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 --flush-logs --hex-blob --triggers --routines --events --all-databases > /tmp/backup/all_db_with_data.sql
注意:如果是MySQL5.7版本有BUG(详情请看五、已知BUG)需要多添加一步操作:
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 --flush-logs --set-gtid-purged=off --hex-blob --triggers --routines --events --tables mysql proc > /tmp/backup/mysql_proc.sql
以上导出的SQL,必须在开启SET @@SESSION.SQL_LOG_BIN= 0;
的情况下,利用mysql> source mysql_proc.sql
的方式导入,否则会造成异常情况影响主从建立,如果不是为了创建主从,可忽略此导入方式。
#不搭建主从复制的情况下:多种导入方式都可
#要搭建主从复制的情况下:mysql> use mysqlmysql> SET @@SESSION.SQL_LOG_BIN= 0;mysql> source /tmp/backup/mysql_proc.sql
## 备份表结构和数据
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 --flush-logs --set-gtid-purged=off --hex-blob --databases employees > /tmp/backup/employees_all.sql## 只备份表结构
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 --flush-logs --set-gtid-purged=off --hex-blob --no-data --databases employees > /tmp/backup/employees_schema.sql## 只备份数据
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 --flush-logs --set-gtid-purged=off --hex-blob --no-create-info --databases employees > /tmp/backup/employees_only_data.sql
## 只备份employees数据库中的salaries表
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 --flush-logs --set-gtid-purged=off --hex-blob --tables employees salaries > /tmp/backup/employees_salaries.sql## 排除指定数据库的指定表
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 --flush-logs --set-gtid-purged=off --hex-blob --ignore-table=employees.departments --ignore-tableployees employees > /tmp/backup/employees_exclude_departments.sql
注意
如果备份时要排除某个数据库中多个表,要使用多个–ignore-table语句,不能在后面加逗号做分割。
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 --flush-logs -T /tmp/salaries --databases employees --tables salaries > employees_salaries.sql
注意事项
less 10001 60117 1986-06-26 1987-06-26
10001 62102 1987-06-26 1988-06-25
10001 66074 1988-06-25 1989-06-25
10001 66596 1989-06-25 1990-06-25
10001 66961 1990-06-25 1991-06-25
只转储由给定的WHERE条件选择的行
###按照where条件,备份指定库下的指定表的数据
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 -w 'id > 10 and id < 20' --databases testdb --tables sbtest1 > /tmp/backup/sbtest1.sql###按照where条件,备份指定库下的所有表的数据
mysqldump -uops -p -h127.0.0.1 -P4444 --default-character-set=utf8mb4 --single-transaction --master-data=2 -w 'id > 10 and id < 20' --databases testdb > /tmp/backup/sbtest1.sql
注意事项
参数 | 建议 | 原因 | 命令 |
---|---|---|---|
autocommit | 建议开启 | 如果关闭,可能会造成导入语句无法自动提交,可能会导致事务卡住、事务回滚、binlog大事务,甚至数据库关闭。 | set session autocommit = 1; |
wait_timeout interactive_timeout | 建议调大 | 设置过小,且导入时间长,会导致还没导入完,会话超时断开连接,导致任务失败。 | set session wait_timeout=28800; set session interactive_timeout=28800; |
less all_db_with_data.sql | grep -E "^DROP TABLE IF EXISTS|^USE"
在一般的备份文件导入中,只能凭经验去估测一下备份文件实际导入的时间,这里可以使用PV工具,较为精确的算出导数剩余量及完成时间,所以建议使用此种方式,进行数据导入
#参数说明:
#-W:在需要密码输入时有用,可等待密码输出完成,再开启监控进度条
#-L:限流,将传输限制在每秒最大字节的范围内(大小可自定义,单位可变)
shell> pv -W -L 2M all_db_with_data.sql | /data/mysql/base/5.7.25/bin/mysql -uops -p -S/data/mysql/data/3333/mysqld.sock
Enter password: 588MiB 0:04:54 [ 2MiB/s] [======================================================>] 100%
#参数说明:
#reset master:在导入机器有自身的GTID时,会导入失败,所以可根据需要在echo里面添加"reset master"命令,清空GTID purge。shell> (echo 'set @@autocommit=1; set @@interactive_timeout=28800; reset master;'; pv -W -L 5M all_db_with_data.sql) | mysql -h127.0.0.1 -P3333 -uops -pshell> (echo 'set @@autocommit=1; set @@interactive_timeout=28800;'; pv -W -L 5M employees_all.sql) | mysql -h127.0.0.1 -P3333 -uops -p employees
防止SQL导入中产生过大的binlog,使主从延迟增加,想在导入时把日志格式改为statement,减小binlog
transaction_isolation
binlog_format
如果表是InnoDB表,并且事务隔离级别是READ COMMITTED或READ UNCOMMITTED,那么只能使用基于行的日志记录。可以将日志格式改为statement,但在运行时这样做会导致错误,因为InnoDB表不能再执行insert语句。
mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| STATEMENT |
+-----------------+
1 row in set (0.00 sec)mysql> show variables like '%iso%';
+-----------------------+----------------+
| Variable_name | Value |
+-----------------------+----------------+
| transaction_isolation | READ-COMMITTED |
| tx_isolation | READ-COMMITTED |
+-----------------------+----------------+
2 rows in set (0.00 sec)mysql> create table test(id int, name varchar(20));
Query OK, 0 rows affected (0.02 sec)mysql> insert into test values(1, 'zhou'),(2, 'wei');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0mysql> select * from test;
+------+------+
| id | name |
+------+------+
| 1 | zhou |
| 2 | wei |
+------+------+
2 rows in set (0.00 sec)mysql> insert into test values(3,'bing');
ERROR 1665 (HY000): Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
在执行备份导入时有将binlog_format临时设置为statement需求时,需要检查transaction_isolation是否为RR。在RC级别下,binlog_format设置为statement会导致不能进行insert相关操作。所以不是RR级别,请不要将binlog_format改为statement。
备份或导入SQL包过大,超过max_allowed_packet,备份或导入失败
max_allowed_packet
备份或导入时确定数据库表中的字符类型:如果有BLOB列或长字符串等字符类型建议合理增加这个值。
# mysqldump -h10.100.143.62 -umeslogin -P3306 -p --default-character-set=utf8mb4 --master-data=2 --flush-logs --single-transaction --set-gtid-purged=off --hex-blob --databases yfmes_metal_sys > yfmes_metal_sys_all.sql
mysqldump: Error 2020: Got packet bigger than 'max_allowed_packet' bytes when dumping table `operlog` at row: 264227
导入时也相似的原理。
可以在mysql、mysqldump等client命令后临时修改此参数:
mysqldump [xxxx] --max_allowed_packet=256M > dump.sql
mysql [xxxx] --max_allowed_packet=256M < dump.sql
easydb
微信公众号:easydb
关注我,不走丢!本文发布于:2024-02-02 01:46:28,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170681359240620.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |