Mysql之mysqldump工具使用

mysqldump

官方文档:https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html

mysqldump客户端是一个mysql自带的逻辑备份工具,可以用导出sql语句形式一次导出多个数据库进行备份。mysqldump还可以生成csv、xml或其他定界符文本。

查看帮助

mysqldump --help

参数

-h: 主机
-P: 端口
-u: 用户名
-p: 密码

--databases: 指定多个数据库,如果是一个数据库可以不写--databases直接写dbname
--tables: 指定表名,以空格分开

-t: 不使用create table建表和drop table语句(--no-create-info)
-d: 不导出表数据(--no-data)

-c:insert语句展示完整字段(--complete-insert)
--replace:使用replace into语句,当值(主键/唯一键)存在时删除旧数据插入新数据
--insert-ignore:使用insert-ignore语句插入,当值(主键/唯一键)存在时忽略新数据保留旧数据

--skip-tz-utc:(对有timestamp字段的表有影响)跳过时区设置。不写默认开启时区+00:00,为了导出的数据能在各个时区的服务器中导入自动转换为所在时区的时间,**记住原则:加了一定不能跨时区服务器执行,没加一定不能把insert语句复制出来单独执行!!!**
-w: 添加表条件,有timestamp字段的条件一定要跳过时区设置(--where=name)

常用命令

mysqldump -u root -p --all-databases > D:/mysql.sql  #备份所有数据库
mysqldump -uroot -p123456 --databases db1 db2 db3 > D:/mysql.sql  #备份多个数据库
mysqldump -hhostname -Pport -uroot -p"123456" --databases dbname > D:/mysql.sql   #远程备份(远程时,需要多加入-h:主机名,-P:端口号)

#带条件导出指定表的部分数据,注意mysqldump导出时时区默认设置为+00:00,w后面的timestamp时间也会被认为是+00:00时区的数据,从而导致数据有问题
mysqldump -h222.222.221.197 -uroot -proot DBname TABLEname -t --complete-insert --skip-tz-utc -w"sys_create > '2020-12-25 16:00:00'">export.sql   

#一次性导出导入数据库(!!!慎用,两个服务器写反了就完蛋了,因为导出的sql中有drop table语句)
mysqldump --host=h1 -uroot -proot --databases db1 |mysql --host=h2 -uroot -proot db2 

#导出为压缩包,这样会小很多,线上服务器尽量用这个,推荐!!!
mysqldump --opt -uroot -p123456 -h127.0.0.1 --databases dbname --ignore-table=dbname.table1 | gzip>/db_back/dbname_`date +%F`.zip    

常用脚本

导出多个库的命令

这个一般用于将数据部署到一台新的数据库上面。

mysqldump -uroot -proot --databases DB1 DB2 DB3 > script_databases.sql

某个库的部分表完整导出

完整导出一个数据库中的指定表,此时没有-t参数,如果有表会先drop在create所以用replace和insert-ignore没有意义。

mysqldump --host=192.168.XX.X -uroot -proot DBNAME --tables TB1 TB2 TB3 TB3 > script_tables.sql
pause

某张表部分数据导出

导出某个数据库下面指定表的部分数据,t(不用drop、create表语句,只要带t,insert-ignore/replace就没必要了),skip-tz-utc(不会进行时区转换,可以直接把sql复制出来执行),insert-ignore(保留旧数据,如果主键/唯一键冲突想保留新数据就用replace)。

mysqldump --host=192.168.XX.X -uroot -proot -t --skip-tz-utc --insert-ignore DBNAME --tables TABLENAME1 -w"sysdate > '2021-01-01 00:00:00'" > script_tb_data1.sql
mysqldump --host=192.168.XX.X -uroot -proot -t --skip-tz-utc --insert-ignore DBNAME --tables TABLENAME2 -w"createdate > '2021-01-01 00:00:00'" > script_tb_data2.sql
pause

导入数据

sql脚本导入到数据库,这个在服务器上执行要慎重检查host(host写成线上库就和删库跑路有异曲同工之妙!)

mysql --host=127.0.0.1 -uroot -proot DBNAME < script_tables.sql

注意坑

导出的insert语句不能复制出来执行

mysqldump语句导出时默认用+00:00时区的,这时导出的sql语句中timestamp都是+00:00时区的,也就是都是-8h的。所以一定要整个文件执行,不能复制出来单独执行!!!,没写--skip-tz-utc的情况下一定不能把insert语句单独拿出来执行!!!!

/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;

-w条件中timestamp条件

-w语句中timestamp字段条件的时间会被认为是+00:00时区的时间(此时库里的timestamp在这个环境下已经是都-8h的数据了)

解决办法:

1.使用--skip-tz-utc(这时导出的sql是不能跨时区服务器导入的)。

2.使用datetime的字段则不会被解析为+00:00时区。

报错

error1044

【错误信息】: mysqldump: Got error: 1044: Access denied for user 'XXX'@'%' to database 'XXX' when doing LOCK TABLES

【报错原因】:mysqldump 命令执行时,需要四种权限,分别是:select,show view,trigger,lock table。但是因为没有lock table的权限,导致上述错误发生。

【解决方案】:

1.用具有select,show view,trigger,lock table全部权限的账户导出.(推荐!!!)

2.添加 --skip-lock-tables使mysqldump导出时不锁表(据说数据量过大会卡死)

3.--single-transaction(网上解释:此选项会将隔离级别设置为REPEATABLE READ。并且随后再执行一条START TRANSACTION语句,让整个数据在dump过程中保证数据的一致性,这个选项对InnoDB的数据表很有用,且不会锁表。但是这个不能保证MyISAM表和MEMORY表的数据一致性。为了确保使用--single-transaction命令时,保证dump文件的有效性。需没有下列语句ALTER TABLE, CREATE TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE,因为一致性读不能隔离上述语句。所以如果在dump过程中,使用上述语句,可能会导致dump出来的文件数据不一致或者不可用。 )

原文地址:https://www.cnblogs.com/aeolian/p/14259114.html