解决mysqldump备份报错:SET OPTION SQL_QUOTE_SHOW_CREATE=1

在使用mysqldump备份数据库的时候报如下错误,

mysqldump: Couldn't execute 'SET OPTION SQL_QUOTE_SHOW_CREATE=1': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'OPTION SQL_QUOTE_SHOW_CREATE=1' at line 1 (1064)

mysqldump命令使用方法参见:http://yanue.net/post-64.html

下面解决方法来源于网络,针对我的版本是mysql5.6,问题解决。

使用命令查看:

rpm -qa | grep -i mysql

经排查发现是数据库版本问题、安装的是mysql5.6 、执行该命令是mysql5.5遗留下来的二进制文件、验证如下

[root@yanue mysql]# which mysqldump
/usr/bin/mysqldump

最后找到解决办法、用新安装的mysql绝对路径来实现备份

#/usr/local/mysql/bin/mysqldump --socket=/tmp/mysql.sock -uroot -p --lock-all-tables zabbix > zabbix.sql

另外:由于mysql server端的版本为5.6,mysql client端的版本为5.5,所以把mysql client端的版本也升到了5.6,再次执行mysqldump就好了.

Docker-MySql — 使用mysqldump 命令备份导出mysql容器中的结构数据

1. 查看当前启动的mysql运行容器

docker ps   

2. 使用以下命令备份导出数据库中的所有表结构和数据

docker exec -it  mysql mysqldump -uroot -p123456 paas_portal > /cloud/sql/paas_portal.sql  

3.只导数据不导结构

mysqldump -t 数据库名 -uroot -p > xxx.sql 
docker exec -it mysql mysqldump -t -uroot -p123456 paas_portal >/cloud/sql/paas_portal_dml.sql  

4. 只导结构不导数据

mysqldump --opt -d 数据库名 -u root -p > xxx.sql 
docker exec -it mysql mysqldump  --opt -d   -uroot -p123456 paas_portal >/cloud/sql/paas_portal_ddl.sql   

5. 导出特定表的结构

mysqldump -uroot -p -B 数据库名 --table 表名 > xxx.sql
docker exec -it mysql mysqldump -uroot -p -B paas_portal --table user > user.sql  

这是工作中用到的,记录下来,以供学习参考

MySQL 5.7并发复制和mysqldump相互阻塞引起的复制延迟

本来MySQL BINLOG和SHOW PROCESSLIST命令属于八竿子打不着的两个事务,但在最近故障排查中,发现主库和从库已经存在很严重的复制延迟,但从库上显示slave_behind_master值为0,复制SQL线程与备份线程之间相互阻塞,但未报死锁。

在从库上执行SHOW PROCESSLIST发现复制的SQL线程等待锁,而等待SQL的WHERE条件竟然是类似于WHERE C1=’ABC’ AND C2>’2018-03-01′ AND C2<‘2018-03-26’ 这种个范围查询,第一时间想到就是怎么是个基于STATEMENT的复制,不科学啊,我们生产环境统一使用基于ROW格式的复制,难道研发私自修改回话级别的复制格式?

使用MySQL Binlog导出日志一看:

未分类

发现真错怪研发同事啦,rbr_only=yes说明基于ROW格式进行复制,“SET TRANSACTION ISOLATION LEVEL READ COMMITTED”也是基于行格式复制的典型特征之一,last_committed和sequence_number用于MySQL 5.7版本中的并发复制,row_query后跟的是在主库上执行的原始SQL,也就是我们在从库SHOW PROCESSLIST中看到的SQL,但实际上从库执行的还是BINLOG部分,该BINLOG可以直接可以直接直接在从库上执行,也可以解析成一行行的数据DML操作,BINLOG部分如下:

未分类

==========================================================================================================

另外一个很有意思的问题,如果在从库上运行mysqldump进行备份,且从库上使用并行复制,会导致备份和复制相互阻塞:

未分类

在上面的阻塞中,多个SQL线程与备份线程相互之间阻塞,且MySQL无法有效检测出死锁环路而触发死锁的回滚机制,导致复制线程和备份作业相互hang住,需要DBA进行干预(取消备份或停止复制),在复制SQL线程被hang住期间,复制的IO线程仍可以正常工作接受到主库的Binlog信息,但slave_behind_master并不会随之增大,如果仅通过监控slave_behind_master值来判断主从复制延迟,则会导致延迟监控存在严重漏洞,因此在监控复制延迟时,除监控slave_behind_master值外,还需要监控主库binlog位置点和从库执行的binlog位置点。

Linux下MySQL定时自动完整备份(mysqldump+crontab)

一、前言

1、本文目标

  • 实现数据库全量备份
  • 实现定时执行备份
  • 实现定时清理7天之前的备份

2、环境信息

未分类

二、备份

  • 目录准备
mkdir /mysql
mkdir /mysql/backup
mkdir /mysql/backup/scripts
mkdir /mysql/backup/files
mkdir /mysql/backup/logs
  • 备份脚本

新建脚本

vi /mysql/backup/scripts/backup_full.sh

脚本内容

#!/bin/bash

#备份目录
BACKUP_ROOT=/mysql/backup
BACKUP_FILEDIR=$BACKUP_ROOT/files
BACKUP_LOGDIR=$BACKUP_ROOT/logs

#当前日期
DATE=$(date +%Y%m%d)

######备份######

#查询所有数据库
#-uroot -p123456表示使用root账号执行命令,且root账号的密码为:123456
DATABASES=$(mysql -uroot -p123456 -e "show databases" | grep -Ev "Database|sys|information_schema")
#DATABASES=$(mysql -uroot -p123456 -e "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN ('sys','mysql','information_schema','performance_schema');" | grep -v "SCHEMA_NAME","ken.io") 
echo $DATABASES
#循环数据库进行备份
for db in $DATABASES
do
echo
echo ----------$BACKUP_FILEDIR/${db}_$DATE.sql.gz BEGIN----------
mysqldump -uroot -pRoot@1024 --default-character-set=utf8 -q --lock-all-tables --flush-logs -E -R --triggers -B ${db} | gzip > $BACKUP_FILEDIR/${db}_$DATE.sql.gz
echo ----------$BACKUP_FILEDIR/${db}_$DATE.sql.gz COMPLETE----------
echo
done

echo "done"

备份测试&验证

#执行备份脚本
sh /mysql/backup/scripts/backup_full.sh

#查看备份文件
ll /mysql/backup/files -h

#解压指定文件({file}自己替换成备份的文件)
gunzip /mysql/backup/files/{file}

三、定时任务

  • 安装crontab
yum install -y crontab

1、定时执行MySQL完整备份

  • 创建定时备份任务
#添加定时任务
crontab -e

#每天凌晨3点执行
00 3 * * * sh /mysql/backup/scripts/backup_full.sh

#查看定时任务
crontab -l

2、定时清理7天以前的备份

  • 创建文件清理脚本
#创建脚本文件
vi /mysql/backup/scripts/backup_full_clean.sh

#写入以下内容
#!/bin/bash
find /mysql/backup/files -mtime +7 -name "*.gz" -exec rm -rf {} ;

创建定时清理任务

#添加定时任务
crontab -e

#每天凌晨1点执行
00 1 * * * sh /mysql/backup/scripts/backup_full_clean.sh

#查看定时任务
crontab -l

四、备注

1、crontab命令示例

未分类

2、本文参考

  • https://blog.csdn.net/zmcyu/article/details/75353245
  • http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/crontab.html

本文由 ken.io 创作,采用CC BY 3.0 CN协议 进行许可。 可自由转载、引用、甚至修改,但需署名作者且注明出处。

mysqldump 参数和使用方法介绍

mysqldump是MySQL数据库自带的一款命令行工具,mysqldump属于单线程,功能是非常强大的,不仅常被用于执行数据备份任务,甚至还可以用于数据迁移。

备份粒度相当灵活,既可以针对整个MySQL服务,也可以只备份某个或者某几个DB,或者还可以指定只备份某个或者某几个表对象,甚至可以实现只备份表中某些符合条件的记录。

mysqldump命令创建的是逻辑备份,它输出的结果集有两种格式:一种是将数据转换成标准SQL语句(一堆 CREATE , DROP ,INSERT等语句);另一种是将数据按照指定的分隔符,输出成定界格式的平面文件。

mysqldump 使用参数很多,但是实际上经常用到的并没有多少。下面我们来介绍一下这些参数:

mysqldump 具体有多少参数,我们可以使用

$ mysqldump  --help

命令查看

1. 常用参数

  • -?, –help: 显示帮助信息,英文的;
  • -u, –user: 指定连接的用户名;
  • -p, –password: 指定用户的密码,可以交互输入密码;
  • -S , –socket: 指定socket文件连接,本地登录才会使用。
  • -h, –host: 指定连接的服务器名称或者IP。
  • -P, –port=: 连接数据库监听的端口。
  • –default-character-set: 设置字符集,默认是UTF8。
  • -A, –all-databases: 导出所有数据库。不过默认情况下是不会导出information_schema库。
  • -B, –databases: 导出指定的某个/或者某几个数据库,参数后面所有名字参量都被看作数据库名,包含CREATE DATABASE创建库的语句。
  • –tables: 导出指定表对象,参数格式为“库名 表名”,默认该参数将覆盖-B/–databases参数。
  • -w, –where: 只导出符合条件的记录。
  • -l, –lock-tables: 默认参数,锁定读取的表对象,想导出一致性备份的话最后使用该参数,会导致无法对表执行写入操作。
  • –single-transaction:
    该选项在导出数据之前提交一个BEGIN SQL语句,BEGIN 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于多版本存储 引擎,仅InnoDB。本选项和–lock-tables 选项是互斥的,因为LOCK TABLES 会使任何挂起的事务隐含提交,使用参数–single-transaction会自动关闭该选项。
    在InnoDB导出时会建立一致性快照,在保证导出数据的一致性前提下,又不会堵塞其他会话的读写操作,相比–lock-tables参数来说锁定粒度要低,造成的影响也要小很多。指定这个参数后,其他连接不能执行ALTER TABLE、DROP TABLE 、RENAME TABLE、TRUNCATE TABLE这类语句,事务的隔离级别无法控制DDL语句。
  • -d, –no-data: 只导出表结构,不导出表数据。
  • -t, –no-create-info: 只导出数据,而不添加CREATE TABLE 语句。
  • -f, –force: 即使遇到SQL错误,也继续执行,功能类似Oracle exp命令中的ignore参数。
  • -F, —flush-logs: 在执行导出前先刷新日志文件,视操作场景,有可能会触发多次刷新日志文件。一般来说,如果是全库导出,建议先刷新日志文件,否则就不用了。
  • –master-data[=#]: 该选项将二进制日志的位置和文件名写入到输出中。该选项要求有RELOAD权限,并且必须启用二进制日志。如果该选项值等于1,位置和文件名被写入CHANGE MASTER语句形式的转储输出,如果你使用该SQL转储主服务器以设置从服务器,从服务器从主服务器二进制日志的正确位置开始。如果选项值等于2,CHANGE MASTER语句被写成SQL注释。如果value被省略,这是默认动作。
  • –master-data选项会启用–lock-all-tables,除非还指定–single-transaction(在这种情况下,只在刚开始转储时短时间获得全局读锁定。又见–single-transaction。在任何一种情况下,日志相关动作发生在转储时。该选项自动关闭–lock-tables。
    所以,我在INNODB引擎的数据库备份时,我会同时使用–master-data=2 和 –single-transaction两个选项。
  • -x, –lock-all-tables: 在导出任务执行期间锁定所有数据库中的所有表,以保证数据的一致性。这是一个全局锁定,并且自动关闭–single-transaction 和–lock-tables 选项。这个参数副作用比较大,这是全库锁定,备份执行过程中,该库无法进行读写操作,不是所有业务场景都能接受的。请慎用。
  • -n, –no-create-db: 不生成建库的语句CREATE DATABASE … IF EXISTS,即使指定–all-databases或–databases这类参数。
  • –triggers: 导出表的触发器脚本,默认就是启用状态。使用–skip-triggers禁用它。
  • -R, –routines: 导出存储过程以及自定义函数。
    在转储的数据库中转储存储程序(函数和程序)。
  • -E, –events: 输出event。
  • –ignore-table: 指定的表对象不做导出,参数值的格式为[db_name,tblname],注意每次只能指定一个值,如果有多个表对象都不进行导出操作的话,那就需要指定多个–ignore-table参数,并为每个参数指定不同的参数值。
  • –add-drop-database: 在任何创建库语句前,附加DROP DATABASE 语句。
  • –add-drop-table: 在任何创建表语句前,附加DROP TABLE语句。这个参数是默认启用状态,可以使用– skip-add-drop-table参数禁用该参数。
  • –add-drop-trigger: 创建任何触发器前,附加DROP TRIGGER语句。
  • –add-locks: 在生成的INSERT语句前附加LOCK语句,该参数默认是启用状态。使用–skip-add-locks参数禁用。
  • -K, –disable-keys: 在导出的文件中输出 ‘/!40000 ALTER TABLE tb_name DISABLE KEYS */; 以及
    ‘/!40000 ALTER TABLE tb_name ENABLE KEYS */; ‘ 等信息。这两段信息会分别放在INSERT语句的前后,也就是说,在插入数据前先禁用索引,等完成数据插入后再启用索引,目的是为了加快导入的速度。该参数默认就是启用状态。可以通过–skip-disable-keys参数来禁用。
  • –opt: 功能等同于同时指定了 –add-drop-table, –add-locks, –create-options, –quick, –extended-insert, –lock-tables, –set-charset, 以及 –disable-keys这些参数。默认就是启用状态。使用–skip-opt来禁用该参数。
  • –skip-opt: 禁用–opt选项,相当于同时禁用 –add-drop-table, –add-locks, –create-options, –quick, –extended-insert, –lock-tables, –set-charset, 及 –disable-keys这些参数。
  • -q, –quick: 导出时不会将数据加载到缓存,而是直接输出。默认就是启用状态。可以使用–skip-quick 来禁用该参数。

2. mysqldump 默认参数

mysqldjmp 默认使用的参数由以下几个:

  • –opt
  • –add-drop-table
  • –add-locks
  • -i,–comments
  • -a,–create-options
  • -e, –extended-insert
  • -l, –lock-tables
  • -q, –quick
  • -K, –disable-keys
  • -Q, –quote-names
  • –dump-date
  • –ssl
  • –triggers
  • –tz-utc

上面这些参数,执行mysqldump 命令的时候默认就会带上的。

3. mysqldump 常用方法

(1) 获取一个完整备份
不锁库备份

$ mysqldump -uusername -p --triggers --routines --events -A -B --single-transaction --master-data=2 > backup.$(date +%F).sql

(2) 导出指定库

$ mysqldump -uusername -p -B dbname > backup.$(date +%F).sql

如果是导出单库也可以不使用-B 参数,无非就是没有创建库的语句。
如果是多个库可以使用如下命令,但是必须使用-B参数

$ mysqldump -uusername -p -B DB1 DB2 DB3 > backup.$(date +%F).sql

(3) 导出指定表的数据和结构

$ mysqldump -uusername -p DBNAME table1 table2 > tablename.sql    

或者使用 –tables 参数

$ mysqldump -uusername -p --tables DBNAME table1 table2 > backup.$(date +%F).sql  

或者

$ mysqldump  -uusername -p DBNAME  --tables table1 table2 table3 > tablename.sql

(4) 导出指定表的结构
不包含数据

$ mysqldump -ubackup -p --no-data  DBNAME table1 table2 > backup.$(date +%F).sql

或者使用–tables参数

$ mysqldump -ubackup -p --no-data DBNAME  --tables table1 table2 > backup.$(date +%F).sql

或者

$ mysqldump -ubackup -p --no-data  --tables DBNAME table1 table2 > backup.$(date +%F).sql

(5) 导出指定表的数据
不包含表结构

$ mysqldump  -uusername -p --no-create-info DBNAME  table1 table2 table3 > backup.$(date +%F).sql

或者使用–tables 参数

$ mysqldump  -uusername -p --no-create-info DBNAME --tables table1 table2 table3 > backup.$(date +%F).sql

或者

$ mysqldump  -uusername -p --no-create-info  --tables DBNAME table1 table2 table3 > backup.$(date +%F).sql

(6) 导出整个数据库结构 (包括表结构)
不包含数据

$ mysqldump -uusername -p --no-data DBNAME > backup.$(date +%F).sql

(7) 导出数据库表结构和数据时排除某些表
使用 –ignore-table 参数

$ mysqldump -uusername -p  --single-transaction --master-data=2 --add-drop-database  -B DBNAME --ignore-table=DBNAME.table1 --ignore-table=DBNAME.table2 > backup.$(date +%F).sql

(8) 导出数据直接压缩

$ mysqldump -uusername -p -B DBNAME | gzip > backup.sql.gz

解压命令:

$ gunzip backup.sql.gz

mysqldump备份失败以及解决方法汇总

mysqldump备份失败以及解决方法汇总

1、mysqldump: Error: Query execution was interrupted, maximum statement execution time exceeded when trying to dump tablespaces
mysqldump: Error 3024: Query execution was interrupted, maximum statement execution time exceeded when dumping table $tb_name at row: xxxx

版本:
MySQL 5.7.8+
原因:
max_execution_time过小
处理思路:
① 通过hints,增大N值(文档说,在hints用法中,将N改为0为无限制,但我测下来不生效,可设置成一个较大值如999999解决)
SELECT /*+ MAX_EXECUTION_TIME(N) */ * FROM t1 LIMIT 100000;
② 修改max_execution_time值,将该值设置为较大一个值,或设置为0(不限制)
附录:
该参数5.7.8被添加,单位为ms,动态参数,默认为0,设置为0时意味着SELECT超时不被设置(不限制超时时间)。不作用于存储过程中的SELECT语句,并且只作用于只读的SELECT,如INSERT … SELECT … 是不被作用的。
for more information:
http://blog.itpub.net/29773961/viewspace-2150443/

2、mysqldump: Couldnt execute SHOW FIELDS FROM $view_name: View $db_name.$view_name references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them (1356)

原因:
该view引用了无效的表,列,函数或者定义者。
处理思路:
可以根据报错信息,进入db,执行SHOW CREATE VIEW $view_nameG,查看该view的定义,逐一检查该view的基表,列,或相关函数与用户是否具有相关权限。考虑重建或删除视图。

3、mysqldump: Couldnt execute show create table $view_name: Illegal mix of collations for operation UNION (1271)

原因:
创建view时,使用UNION时存在非法的排序规则组合。
处理思路:
检查该视图定义,检查字符集,考虑重建或删除视图。

4、mysqldump: Couldnt execute SHOW FIELDS FROM $view_name: The user specified as a definer ($user@$host) does not exist (1449)
mysqldump: Couldnt execute show table status like $view_name: SELECT command denied to user @% for column $col_name in table $tb_name (1143)

原因:
该视图的定义者$user@$host不存在。
处理思路:
检查mysql.user表,确认用户是否存在,考虑重建或删除视图。

5、Error: Couldnt read status information for table Income_config ()mysqldump: Couldnt execute show create table Tser_table: Table $db_name.test_table doesnt exist (1146)
mysqldump: Got error: 1049: Unknown database $db_name when selecting the database

原因一:
从lower_case_table_names的0设置成1,导致部分原来含有大写字母的库表“找不到”。
处理思路:
将lower_case_table_names设置回0。
若有必须将lower_case_table_names设置为1,需先设置为0,并将含有大写字母的库表改成小写,再设置为1。

原因二(MySQL 5.5及以下版本可能出现):
表损坏导致该表找不到(InnoDB)。frm和ibd文件都在,但无法SHOW CREATE TABLE xxxG
error log一则:

170820 17:43:17 [Note] Event Scheduler: scheduler thread started with id 1
170820 17:44:48 InnoDB: error: space object of table '$db_name/$tb_name',
InnoDB: space id 4335 did not exist in memory. Retrying an open.
170820 17:44:48 InnoDB: Error: tablespace id and flags in file './$db_name/$tb_name.ibd' are 0 and 0, but in the InnoDB
InnoDB: data dictionary they are 4335 and 0.
InnoDB: Have you moved InnoDB .ibd files around without using the
InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?
InnoDB: Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/innodb-troubleshooting-datadict.html
InnoDB: for how to resolve the issue.
170820 17:44:48 InnoDB: cannot calculate statistics for table $db_name/$tb_name
InnoDB: because the .ibd file is missing. For help, please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/innodb-troubleshooting.html
170820 17:44:48 [ERROR] MySQL is trying to open a table handle but the .ibd file for
table $db_name/$tb_name does not exist.
Have you deleted the .ibd file from the database directory under
the MySQL datadir, or have you used DISCARD TABLESPACE?
See http://dev.mysql.com/doc/refman/5.5/en/innodb-troubleshooting.html
how you can resolve the problem.

处理思路:
从完整备份+binlog还原,对于有主或从的实例,可通过物理备份还原。

6、mysqldump: Error 2020: Got packet bigger than max_allowed_packet bytes when dumping table $tb_name at row: xxxx

原因:
默认的max_allowed_packet过小
处理思路:
在mysqldump时增加max_allowed_packet的大小,如mysqldump –max-allowed-packet=268435456

7、mysqldump: Error 1412: Table definition has changed, please retry transaction when dumping table $tb_name at row: 0

原因:
在备份该表时,表定义被修改。FLUSH TABLE WITH READ LOCK只保证数据一致性,并不保证schema不被修改。
处理思路:
备份时期不做DDL操作。
复现一:

① session1> CREATE TABLE a (id int) ENGINE=InnoDB;
② session2> START TRANSACTION WITH CONSISTENT SNAPSHOT;
③ session1> ALTER TABLE a ADD COLUMN name varchar(32);
④ session2> SELECT * FROM a;
ERROR 1412 (HY000): Table definition has changed, please retry transaction

p.s. 如果③和④调换顺序,则ALTER TABLE无法成功,则会等待MDL。
复现二:

① session1> START TRANSACTION WITH CONSISTENT SNAPSHOT;
② session2> CREATE TABLE b (id int) ENGINE=InnoDB;
③ session1> SELECT * FROM b;
ERROR 1412 (HY000): Table definition has changed, please retry transaction

8、mysqldump: Couldnt execute show create table $tb_name: Unable to open underlying table which is differently defined or of non-MyISAM type or doesnt exist (1168)

原因:
出现在表引擎为MERGE时,备份到该表时,发现该表定义存在问题。可能merge的表不存在,或者该表合并的基表包含非MyISAM引擎的表。
处理思路:
删除或者重建该MERGE表。
复现一(merge表中定义包含了非MyISAM表):

CREATE TABLE t1(id int) ENGINE=InnoDB;
CREATE TABLE t2(id int) ENGINE=MyISAM;
CREATE TABLE merge_t(id int)ENGINE=MERGE UNION=(t1, t2);
SELECT * FROM merge_t;
ERROR 1168 (HY000): Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist

复现二(表不存在):

CREATE TABLE t1(id int) ENGINE=MyISAM;
CREATE TABLE t2(id int) ENGINE=MyISAM;
CREATE TABLE merge_t(id int)ENGINE=MERGE UNION=(t1, t2);
SELECT * FROM merge_t;
Empty set (0.00 sec)    -- 正常返回
DROP TABLE t1;
SELECT * FROM merge_t;
ERROR 1168 (HY000): Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist

附录:
通过check table merge_t可以检查是哪张表有问题,如此处是t1:

[15:20:12] root@localhost [test]> check table merge_tG
*************************** 1. row ***************************
  Table: test.merge_t
     Op: check
Msg_type: Error
Msg_text: Table 'test.t1' is differently defined or of non-MyISAM type or doesn't exist
*************************** 2. row ***************************
  Table: test.merge_t
     Op: check
Msg_type: Error
Msg_text: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
*************************** 3. row ***************************
  Table: test.merge_t
     Op: check
Msg_type: error
Msg_text: Corrupt
3 rows in set (0.00 sec)

通过cat表MGR定义结构文件可以检查MERGE表的基表:

[root@host test]# pwd
/data/mysql-data/mysql57/data/test
[root@host test]# cat merge_t.MRG
t1
t2

9、mysqldump: Couldnt execute show create table $tb_name: Table ./$db_name/$tb_name is marked as crashed and last (automatic?) repair failed (144)
mysqldump: Couldnt execute show create table $tb_name: Table ./$db_name/$tb_name is marked as crashed and should be repaired (145)
mysqldump: Error 1194: Table throne_tower is marked as crashed and should be repaired when dumping table $tb_name at row: xxxxx

原因:
mysqldump在拉取表定义时报错,表损坏。
处理思路:
该损坏发生在非事务表如MyISAM,通过mysqlcheck或者repair table修复即可。

10、mysqldump: Couldnt execute SHOW FUNCTION STATUS WHERE Db = $db_name: Cannot load from mysql.$tb_name. The table is probably corrupted (1728)

原因:
字典表不正确,可能是表本身损坏,也有可能是导入了其他版本的mysql schema盖掉了字典表。
处理思路:
repair table修复,若仍无用,则可以尝试mysql_upgrade来修复,或找到对应版本的mysql_system_tables_fix.sql来导入。

11、mysqldump: Couldnt execute show events: Cannot proceed because system tables used by Event Scheduler were found damaged at server start (1577)

原因:
字典表不正确,极大可能是导入了其他版本的mysql schema盖掉了字典表。
处理思路:
尝试mysql_upgrade来修复,或找到对应版本的mysql_system_tables_fix.sql来导入。该报错可能在upgrade操作之后重启实例。

12、mysqldump: Error: Got error 28 from storage engine when trying to dump tablespaces
mysqldump: Couldnt execute show fields from $tb_name: Got error 28 from storage engine (1030)

原因:
@@tmpdir满了。
处理思路:
清除@@tmpdir,可以通过SELECT @@tmpdir;检查具体目录。

13、mysqldump: Lost connection to MySQL server during query (2013)
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘@@socket’ (111)

原因:
mysqldump执行过程中mysqld被关闭。
处理思路:
检查mysqld被关闭的原因,一般常见原因是发生OOM。

14、mysqldump: Couldn’t execute ‘SHOW SLAVE STATUS’: Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation (1227)

原因:
mysqldump加了–dump-slave参数,缺少SUPER或REPLICATION CLIENT来执行SHOW SLAVE STATUS。
处理思路:
检查mysqldump的用户权限。

15、mysqldump: Couldn’t execute ‘STOP SLAVE SQL_THREAD’: Access denied for user ‘dump’@’localhost’ (using password: YES) (1045)

原因:
mysqldump加了–dump-slave参数,缺少SUPER权限使用STOP SLAVE SQL_THREAD。
处理思路:
检查mysqldump的用户权限。

使用mysqldump时,显示MySQL server has gone away

mysqldump 是导出及导入MySQL数据库的常用命令,当我们导入或导出较大数据库时偶尔会遇到如下错误信息。

ERROR 2006 (HY000) at line **: MySQL server has gone away

一般情况下是因为 max_allowed_packet 参数(默认值为1MB)的限制所导致的,因此我们需要调整该参数并重启MySQL。

查看当前的max_allowed_packet的大小。

show variables like 'max_allowed_packet';
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+

修改 /etc/my.cnf 文件之后,重启MySQL。

[mysqld]
max_allowed_packet = 32MB

max_allowed_packet 是控制从客户端向MySQL服务端可传送包(packet)的大小的参数,因此需要传送较大文件时提前修改该参数。

crontab mysqldump 定时任务 备份 及 创建文件 大小 为 0 解决方案+分析

今天现网Mysql数据库要求开始做备份,于是决定把mysqldump命令写到脚本里,然后做到crontab里让它每天定时执行。
系统:RHEL6.5,Mysql5.5

路径:/tmp/tmp
mysqldump写到test.sh,:wq保存后,赋予执行权限:

mysqldump -A -uroot -pyourpassword > /tmp/tmp/mysqlallbak.sql
chmod a+x test.sh

接下来手工执行一下

./test.sh
[root@neoska tmp]# ll
total 648
-rw-r--r-- 1 root root   662849 Nov 29 10:20 mysqlallbak.sql

有sql文件生成,文件大小不为0,一切正常,美滋滋。

接下来删掉那个sql文件,做定时任务,把脚本加入定时执行,设10点22

crontab -e
22 10 * * * /tmp/tmp/test.sh

时间一到,马上到tmp下查看

[root@neoska tmp]# ll
total 0
-rw-r--r-- 1 root root 0 Nov 29 10:22 mysqlallbak.sql

文件确实有,可大小为0,打开看就是个空文件。

检查步骤:

1.打开脚本仔细检查,看是不是语句里忘写mysql登陆密码。
2.脚本检查无误,crontab -e仔细检查定时任务是否有误。
3.crontab检查无误,开始怀疑crontab本身有问题。百度了一下,大多数解决方案是,mysqldump命令写成绝对路径即可。
于是

[root@neoska tmp]# find / -name mysqldump
/usr/local/mysql/bin/mysqldump

打开脚本,把mysqldump换成/usr/local/mysql/bin/mysqldump,重新crontab测试,果然奏效了。
4.用绝对路径写了脚本,测了几次,没问题。但手工执行成功,定时任务挂掉,百思不得其解,遂继续百度之。
原来crontab运行时,使用自己的环境变量,相当于独立的环境。
其自动运行的环境配置写在/etc/crontab。
于是打开看看

[root@neoska tmp]# vim /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed

!有个PATH长的好像系统环境变量PATH!
这个path里,没有步骤3中mysqldump的路径,因此肯定是crontab的环境找不到mysqldump指令,自然也不能执行成功。
原因弄明白了,问题就好解决了。

  • 方案1
    采用软链接方式,将mysqldump软链接到crontab配置文件中PATH后面的任意一个下,如/usr/bin:
 ln -s /usr/local/mysql/bin/mysqldump /usr/bin/mysqldump

回去编辑脚本,把mysqldump的绝对路径删掉,保存重新crontab测试,成功。

  • 方案2
    修改/etc/crontab的内容,在PATH最后面加上:/Your_project_path(注意冒号别掉了)(此处就是mysqldump的存放路径/usr/local/mysql/bin/)保存退出。
    没有软链接的情况下,测试成功。

总结

crontab运行采用独立环境,PATH变量可在/etc/crontab文件中编辑。不只是mysql或mysqldump,所有自定义的命令,都可采用这两种方法,让crontab能够找到该指令,这样就不会出现crontab定时脚本不能执行的现象。
另外,一些需要更改环境变量才能执行的项目,可以在脚本开头写上source /etc/profile或者JAVA_HOME=XXXXX/export XXXXX(使用指定jdk等),来指定该脚本需要的环境变量。

参考资料

Linux中crontab的坑爹环境变量问题
http://blog.csdn.net/dancen/article/details/24355287
corantab 不能自动执行的一些问题-环境变量
http://xiachaofeng.iteye.com/blog/1405184
mysqldump参数之-A -B
http://blog.csdn.net/u010587433/article/details/47417051

附录

完整脚本

#创建一个以当天日期为名的文件夹如171129
mkdir -p /home/neoska/backup/data/`date +%Y%m%d`

#写备份文件,-A为备份所有库。其他常用选项:-B database1 database2 ...为指定的多个库,-d为只导出表结构,-h10.11.12.13为备份IP为10.11.12.13的远程数据库。
mysqldump -A -uroot -ppasswd > /home/neoska/backup/data/`date +%Y%m%d`/mysqldumpall.sql

#删掉3天前的备份数据,可自定义周期,若数据太大则应设小点以免磁盘写满。
rm -rf /home/neoska/backup/data/`date +%Y%m%d -d "-3days"`

Mysql必读mysql数据库备份及恢复命令 mysqldump,source的用法

还原一个数据库:

mysql -h localhost -u root -p123456 www<c:www.sql 

备份一个数据库:

mysqldump -h localhost -u root -p123456 www > d:www2008-2-26.sql 

//以下是在程序中进行测试

//$command = "mysqldump --opt -h $dbhost -u $dbuser -p $dbpass $dbname | gzip > $backupFile"; 
$command="mysqldump -h localhost -u root -p123456 guestbook > guestbook2-29.sql"; 
system($command); 
echo "success"; 

备份MySQL数据库的命令

mysqldump -hhostname -uusername -ppassword databasename > backupfile.sql 

备份MySQL数据库为带删除表的格式,能够让该备份覆盖已有数据库而不需要手动删除原有数据库.

mysqldump -Cadd-drop-table -uusername -ppassword databasename > backupfile.sql 

直接将MySQL数据库压缩备份

mysqldump -hhostname -uusername -ppassword databasename | gzip > backupfile.sql.gz 

备份MySQL数据库某个(些)表

mysqldump -hhostname -uusername -ppassword databasename specific_table1 specific_table2 > backupfile.sql 

同时备份多个MySQL数据库

mysqldump -hhostname -uusername -ppassword Cdatabases databasename1 databasename2 databasename3 > multibackupfile.sql 

仅仅备份数据库结构

mysqldump Cno-data Cdatabases databasename1 databasename2 databasename3 > structurebackupfile.sql 

备份服务器上所有数据库

mysqldump Call-databases > allbackupfile.sql 

还原MySQL数据库的命令

mysql -hhostname -uusername -ppassword databasename < backupfile.sql 

还原压缩的MySQL数据库

gunzip < backupfile.sql.gz | mysql -uusername -ppassword databasename 

将数据库转移到新服务器

mysqldump -uusername -ppassword databasename | mysql Chost=*.*.*.* -C databasename 

几个常用用例:

1、导出整个数据库

mysqldump -u 用户名 -p 数据库名 > 导出的文件名 
mysqldump -u root -p dataname >dataname.sql 

这个时候会提示要你输入root用户名的密码,输入密码后dataname数据库就成功备份在mysql/bin/目录中.

2、导出一个表

mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名 
mysqldump -u root -p dataname users> dataname_users.sql 

3、导出一个数据库结构

mysqldump -u wcnc -p -d Cadd-drop-table smgp_apps_wcnc >d:wcnc_db.sql 
-d 没有数据 Cadd-drop-table 在每个create语句之前增加一个drop table 

4、导入数据库

常用source 命令
进入mysql数据库控制台,
如mysql -u root -p

mysql>use 数据库

然后使用source命令,后面参数为脚本文件(如这里用到的.sql)

mysql>source d:wcnc_db.sql 

mysqldump支持下列选项:

  • Cadd-locks
    在每个表导出之前增加LOCK TABLES并且之后UNLOCK TABLE.(为了使得更快地插入到MySQL).

  • Cadd-drop-table
    在每个create语句之前增加一个drop table.

  • Callow-keywords
    允许创建是关键词的列名字.这由表名前缀于每个列名做到.

  • -c, Ccomplete-insert
    使用完整的insert语句(用列名字).

  • -C, Ccompress
    如果客户和服务器均支持压缩,压缩两者间所有的信息.

  • Cdelayed
    用Insert DELAYED命令插入行.

  • -e, Cextended-insert
    使用全新多行Insert语法.(给出更紧缩并且更快的插入语句)

  • -#, Cdebug[=option_string]
    跟踪程序的使用(为了调试).

  • Chelp
    显示一条帮助消息并且退出.

Cfields-terminated-by=… 

Cfields-enclosed-by=… 

Cfields-optionally-enclosed-by=… 

Cfields-escaped-by=… 

Cfields-terminated-by=… 

这些选择与-T选择一起使用,并且有相应的LOAD DATA INFILE子句相同的含义.
LOAD DATA INFILE语法.

  • -F, Cflush-logs
    在开始导出前,洗掉在MySQL服务器中的日志文件.

  • -f, Cforce,
    即使我们在一个表导出期间得到一个SQL错误,继续.

  • -h, Chost=..
    从命名的主机上的MySQL服务器导出数据.缺省主机是localhost.

  • -l, Clock-tables.
    为开始导出锁定所有表.

  • -t, Cno-create-info
    不写入表创建信息(Create TABLE语句)

  • -d, Cno-data
    不写入表的任何行信息.如果你只想得到一个表的结构的导出,这是很有用的!

  • Copt
    同Cquick Cadd-drop-table Cadd-locks Cextended-insert Clock-tables.
    应该给你为读入一个MySQL服务器的尽可能最快的导出.

  • -pyour_pass, Cpassword[=your_pass]
    与服务器连接时使用的口令.如果你不指定“=your_pass”部分,mysqldump需要来自终端的口令.

  • -P port_num, Cport=port_num
    与一台主机连接时使用的TCP/IP端口号.(这用于连接到localhost以外的主机,因为它使用 Unix套接字.)

  • -q, Cquick
    不缓冲查询,直接导出至stdout;使用mysql_use_result()做它.

  • -S /path/to/socket, Csocket=/path/to/socket
    与localhost连接时(它是缺省主机)使用的套接字文件.

  • -T, Ctab=path-to-some-directory
    对于每个给定的表,创建一个table_name.sql文件,它包含SQL Create 命令,和一个table_name.txt文件,它包含数据.注意:这只有在mysqldump运行在mysqld守护进程运行的同一台机器上的时候才工作..txt文件的格式根据Cfields-xxx和 ClinesCxxx选项来定.

  • -u user_name, Cuser=user_name
    与服务器连接时,MySQL使用的用户名.缺省值是你的Unix登录名.

  • -O var=option, Cset-variable var=option
    设置一个变量的值.可能的变量被列在下面.

  • -v, Cverbose
    冗长模式.打印出程序所做的更多的信息.

  • -V, Cversion
    打印版本信息并且退出.

  • -w, Cwhere=’where-condition’
    只导出被选择了的记录;注意引号是强制的!
    “Cwhere=user=’jimf’” “-wuserid>1″ “-wuserid<1″

最常见的mysqldump使用可能制作整个数据库的一个备份:

mysqldump Copt database > backup-file.sql 

但是它对用来自于一个数据库的信息充实另外一个MySQL数据库也是有用的:

mysqldump Copt database | mysql Chost=remote-host -C database 

由于mysqldump导出的是完整的SQL语句,所以用mysql客户程序很容易就能把数据导入了:

shell> mysqladmin create target_db_name 
shell> mysql target_db_name < backup-file.sql 

就是

shell> mysql 库名 < 文件名

结合mysqlbinlog与mysqldump进行MySQL数据备份与恢复(适用于较小的数据量)

通过mysqlbinlog工具备份二进制日志文件

mysqlbinlog  --read-from-remote-server --host=192.168.83.37 --port=55944 --user=us_yanzhaozhang --password --raw --to-last-log VMS00782-bin.000001
mysqlbinlog  --read-from-remote-server --host=192.168.83.37 --port=55944 --user=us_yanzhaozhang --password VMS00782-bin.000001  VMS00782-bin.000002  VMS00782-bin.000003 ...  VMS00782-bin.000017  

上述两条命令会将mysqlbinlog连接到的主机中的由VMS00782-bin.000001开始至最后一个二进制日志文件备份到启动mysqlbinlog的目录中。其中–raw参数表明输出二进制格式的文件而非文本格式,–read-from-remote-serve参数表明要连接至该server请求其二进制日志。需要注意的是即使是在本地也需要列出–read-from-remote-server参数。

默认情况下,上述命令会在备份完成后立即断开连接,若想保持连接进行持续备份可添加–stop-never参数。

mysqlbinlog  --read-from-remote-server --host=192.168.83.37 --port=55944 --user=us_yanzhaozhang --password --raw --stop-never VMS00782-bin.000001

指定了–stop-never参数后无需再指定–to-last-log参数。

默认情况下,mysqlbinlog 备份的二进制日志文件保持原名,且存放在当前目录中。可通过–result-file参数改变这个行为,该参数指定了输出文件名的前缀,假定原名为VMS00782-bin.000009,若指定–result-file=x则输出
为xVMS00782-bin.000001,若指定–result-file=/backup/则输出为/backup/VMS00782-bin.000001,若指定–result-file=/backup/x则输出为/backup/xVMS00782-bin.000001。

使用mysqldump和mysqlbinlog进行备份和恢复

假定欲备份的主机中第一个二进制日志文件为VMS00782-bin.000010
首先使用mysqlbinlog进行二进制日志文件的持续备份

mysqlbinlog  --read-from-remote-server --host=192.168.83.37 --port=55944 --user=us_yanzhaozhang --password --raw --stop-never VMS00782-bin.000010

然后使用mysqldump创建备份文件

mysqldump --host=192.168.83.37 --port=55944 --user=us_yanzhaozhang --password --all-databases --events --routines --master-data=2 > dump.sql

若发生数据丢失则使用最近的备份来恢复数据

mysql --host=192.168.83.37 -uus_yanzhaozhang -p -P55944 < dump.sql

根据dump.sql备份文件中– CHANGE MASTER TO MASTER_LOG_FILE=’VMS00782-bin.000018′, MASTER_LOG_POS=27284语句中的二进制日志文件名和位置重新执行该坐标之后的二进制日志备份文件中的事件。

若最新的二进制日志备份文件为VMS00782-bin.000020,如下重新执行日志事件

mysqlbinlog --start-position=27284 VMS00782-bin.000018 VMS00782-bin.000019 VMS00782-bin.000020| mysql --host=192.168.83.37 -uus_yanzhaozhang -p -P55944