Answers:
这将为您提供数据的准确时间点快照:
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql
--single-transaction
产生一个检查点,使转储在接收传入的更改时捕获该检查点之前的所有数据。这些传入的更改不会成为转储的一部分。这样可以确保所有表的时间点相同。
--routines
转储所有存储过程和存储函数
--triggers
为具有触发器的每个表转储所有触发器
您将必须强加全局读取锁,执行mysqldump并释放全局锁
mysql -uuser -ppass -Ae"FLUSH TABLES WITH READ LOCK; SELECT SLEEP(86400)" &
sleep 5
mysql -uuser -ppass -ANe"SHOW PROCESSLIST" | grep "SELECT SLEEP(86400)" > /tmp/proclist.txt
SLEEP_ID=`cat /tmp/proclist.txt | awk '{print $1}'`
echo "KILL ${SLEEP_ID};" > /tmp/kill_sleep.sql
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql
mysql -uuser -ppass -A < /tmp/kill_sleep.sql
试试看 !!!
由于您的总数据少于50MB,因此我有另一种选择。与其在后台启动SLEEP命令以保持全局读取锁定86400秒(即24小时)只是为了获取进程ID并杀死外部,我们不如尝试在mysql中而不是在OS中设置5秒超时:
SLEEP_TIMEOUT=5
SQLSTMT="FLUSH TABLES WITH READ LOCK; SELECT SLEEP(${SLEEP_TIMEOUT})"
mysql -uuser -ppass -Ae"${SQLSTMT}" &
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql
对于非常小的数据库,这是一种更干净,更简单的方法。
ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during query
预期的错误消息吗?
如果要对MyISAM或混合表执行此操作,而又不会因锁定表而造成任何停机,则可以设置一个从数据库,并从那里获取快照。不幸的是,设置从数据库会导致导出实时数据库的停机时间,但是一旦运行该数据库,您应该能够锁定它的表,并使用其他人描述的方法进行导出。发生这种情况时,它将落后于主服务器,但不会阻止主服务器更新其表,并且在备份完成后会立即赶上。
这是我的方法。由于使用,它应该在所有情况下都有效FLUSH TABLES WITH READ LOCK
。
#!/bin/bash
DB=example
DUMP_FILE=export.sql
# Lock the database and sleep in background task
mysql -uroot -proot $DB -e "FLUSH TABLES WITH READ LOCK; DO SLEEP(3600);" &
sleep 3
# Export the database while it is locked
mysqldump -uroot -proot --opt $DB > $DUMP_FILE
# When finished, kill the previous background task to unlock
kill $! 2>/dev/null
wait $! 2>/dev/null
echo "Finished export, and unlocked !"
shell sleep
命令只是为了确保在运行mysqldump之前执行运行mysql lock命令的后台任务。您可以将其减少到1秒,但仍然可以。将其增加到30秒,然后在那30秒内尝试将值插入另一个客户端的任何表中,您会看到它已被锁定。
使用此手动背景锁定有两个优点,而不是使用mysqldump
options --single-transaction
和--lock-tables
:
mysqldump
在相同的锁定期间,您还可以运行除以外的其他命令。例如,在主节点上设置复制时,这很有用,因为您需要获得二进制日志位置以及SHOW MASTER STATUS;
创建的转储的确切状态(在解锁数据库之前),才能创建复制从属。mysql官方文档的建议是,您应该有一个主“ M1”数据库和一个从属“ S1”数据库,如在“方案2:使用只读从属进行 备份”中所述,通过备份它来备份主或从属只读
您应该将从数据库设置为只读并执行
如果MYISAM表很大,并且需要不加锁地转储该表并避免高服务器负载,则可以使用以下脚本。
#!/bin/sh
my_user="user"
my_password="password"
my_db="vpn"
my_table="traffic"
my_step=100000
read -p "Dumping table ${my_db}.${my_table} to ${my_table}.sql?" yn
case $yn in
[Yy]* ) break;;
* ) echo "User cancel."; exit;;
esac
my_count=$(mysql $my_db -u $my_user -p$my_password -se "SELECT count(*) FROM $my_table")
my_count=$(($my_count + 0))
if [ ! $my_count ]
then
echo "No records found"
exit
fi
echo "Records in table ${my_db}.${my_table}: ${my_count}"
echo "" > $my_table.sql
max_progress=60
for (( limit=0; limit<=$my_count; limit+=$my_step )); do
progress=$((max_progress * ( limit + my_step) / my_count))
echo -ne "Dumping ["
for ((i=0; i<$progress; i ++)); do
echo -ne "#"
done
for ((; i<$max_progress; i ++)); do
echo -ne "."
done
mysqldump -u $my_user -p$my_password --complete-insert --no-create-info --opt --where="1 limit $limit , $my_step" $my_db $my_table >> $my_table.sql
echo "" >> $my_table.sql
echo -ne "] $((100 * ( limit + my_step ) / my_count)) %"
echo -ne "\r"
sleep 1
done
echo -ne "\n"