- 其实 的这个问题是mysql中的一个核心问题,既mysql数据的备份和恢复
可以使用三种方式
1.使用sql语句导入导出
2.使用mysqldump 和mysqlimport 工具
3.直接copy 数据文件 既冷备份
说说的详细,就给积分,那 就说详细些
一.使用sql语句完成mysql的备份和恢复
可以使用select into outfile语句备份数据,并用load data infile语句恢复数据。这种方法只能导出数据的内容,不包括表的结构,如果表的结构文件损坏, 必须要先恢复原来的表的结构。
语法:
select * into {outfile | dumpfile} 'file_name' from tbl_name
load data [low_priority] [local] infile 'file_name.txt' [replace | ignore]
into table tbl_name
select ... into outfile 'file_name'格式的select语句将选择的行写入一个文件。文件在服务器主机上被创建,并且不能是已经存在的(不管别的,这可阻止数据库表和文件例如“/etc/passwd”被破坏)。select ... into outfile是load data infile逆操作。
load data infile语句从一个文本文件中以很高的速度读入一个表中。如果指定local关键词,从客户主机读文件。如果local没指定,文件必须位于服务器上。(local在mysql3.22.6或以后版本中可用。)
为了安全原因,当读取位于服务器上的文本文件时,文件必须处于数据库目录或可被所有人读取。另外,为了对服务器上文件使用load data infile,在服务器主机上 必须有file的权限。使用这种select into outfile语句,在服务器主机上 必须有file权限。
为了避免重复记录,在表中 需要一个primary key或unique索引。当在唯一索引值上一个新记录与一个老记录重复时,replace关键词使得老记录用一个新记录替代。如果 指定ignore,跳过有唯一索引的现有行的重复行的输入。如果 不指定任何一个选项,当找到重复索引值时,出现一个错误,并且文本文件的余下部分被忽略时。
如果 指定关键词low_priority,load data语句的执行被推迟到没有其他客户读取表后。
使用local将比让服务器直接存取文件慢些,因为文件的内容必须从客户主机传送到服务器主机。在另一方面, 不需要file权限装载本地文件。如果 使用local关键词从一个本地文件装载数据,服务器没有办法在操作的当中停止文件的传输,因此缺省的行为好像ignore被指定一样。
当在服务器主机上寻找文件时,服务器使用下列规则:
如果给出一个绝对路径名,服务器使用该路径名。
如果给出一个有一个或多个前置部件的相对路径名,服务器相对服务器的数据目录搜索文件。
如果给出一个没有前置部件的一个文件名,服务器在当前数据库的数据库目录寻找文件。
假定表tbl_name具有一个primary key或unique索引,备份一个数据表的过程如下:
1、锁定数据表,避免在备份过程中,表被更新
mysql>lock tables read tbl_name;
关于表的锁定的详细信息,将在下一章介绍。
2、导出数据
mysql>select * into outfile ‘tbl_name.bak’ from tbl_name;
3、解锁表
mysql>unlock tables;
相应的恢复备份的数据的过程如下:
1、为表增加一个写锁定:
mysql>lock tables tbl_name write;
2、恢复数据
mysql>load data infile ‘tbl_name.bak’
->replace into table tbl_name;
如果, 指定一个low_priority关键字,就不必如上要对表锁定,因为数据的导入将被推迟到没有客户读表为止:
mysql>load data low_priority infile ‘tbl_name’
->replace into table tbl_name;
3、解锁表
mysql->unlocak tables;
5.3.2使用mysqlimport恢复数据
如果 仅仅恢复数据,那么完全没有必要在客户机中执行sql语句,因为 可以简单的使用mysqlimport程序,它完全是与load data 语句对应的,由发送一个load data infile命令到服务器来运作。执行命令mysqlimport --help,仔细查看输出, 可以从这里得到帮助。
shell> mysqlimport [options] db_name filename ...
对于在命令行上命名的每个文本文件,mysqlimport剥去文件名的扩展名并且使用它决定哪个表导入文件的内容。例如,名为“patient.txt”、“patient.text”和“patient”将全部被导入名为patient的一个表中。
常用的选项为:
-c, --compress 如果客户和服务器均支持压缩,压缩两者之间的所有信息。
-d, --delete 在导入文本文件前倒空表格。
l, --lock-tables 在处理任何文本文件前为写入所定所有的表。这保证所有的表在服务器上被同步。
--low-priority,--local,--replace,--ignore分别对应load data语句的low_priority,local,replace,ignore关键字。
例如恢复数据库db1中表tbl1的数据,保存数据的文件为tbl1.bak,假定 在服务器主机上:
shell>mysqlimport --lock-tables --replace db1 tbl1.bak
这样在恢复数据之前现对表锁定,也可以利用--low-priority选项:
shell>mysqlimport --low-priority --replace db1 tbl1.bak
如果 为远程的服务器恢复数据,还可以这样:
shell>mysqlimport -c --lock-tables --replace db1 tbl1.bak
当然,解压缩要消耗cpu时间。
象其它客户机一样, 可能需要提供-u,-p选项以通过身分验证,也可以在选项文件my.cnf中存储这些参数,具体方法和其它客户机一样,这里就不详述了。
二、使用mysqldump备份数据
同mysqlimport一样,也存在一个工具mysqldump备份数据,但是它比sql语句多做的工作是可以在导出的文件中包括sql语句,因此可以备份数据库表的结构,而且可以备份一个数据库,甚至整个数据库系统。
mysqldump [options] database [tables]
mysqldump [options] --databases [options] db1 [db2 db3...]
mysqldump [options] --all-databases [options]
如果 不给定任何表,整个数据库将被倾倒。
通过执行mysqldump --help, 能得到 mysqldump的版本支持的选项表。
1、备份数据库的方法
例如,假定 在服务器主机上备份数据库db_name
shell> mydqldump db_name
当然,由于mysqldump缺省时把输出定位到标准输出, 需要重定向标准输出。例如,把数据库备份到bd_name.bak中:
shell> mydqldump db_name>db_name.bak
可以备份多个数据库,注意这种方法将不能指定数据表:
shell> mydqldump --databases db1 db1>db.bak
也可以备份整个数据库系统的拷贝,不过对于一个庞大的系统,这样做没有什么实际的价值:
shell> mydqldump --all-databases>db.bak
虽然用mysqldump导出表的结构很有用,但是恢复大量数据时,众多sql语句使恢复的效率降低。 可以通过使用--tab选项,分开数据和创建表的sql语句。
-t,--tab= 在选项指定的目录里,创建用制表符(tab)分隔列值的数据文件和包含创建表结构的sql语句的文件,分别用扩展名.txt和.sql表示。该选项不能与--databases或--all-databases同时使用,并且mysqldump必须运行在服务器主机上。
例如,假设数据库db包括表tbl1,tbl2, 准备备份它们到/var/mysqldb
shell>mysqldump --tab=/var/mysqldb/ db
其效果是在目录/var/mysqldb中生成4个文件,分别是tbl1.txt、tbl1.sql、tbl2.txt和tbl2.sql。
2、mysqldump实用程序时的身份验证的问题
同其他客户机一样, 也必须提供一个mysql数据库帐号用来导出数据库,如果 不是使用匿名用户的话,可能需要手工提供参数或者使用选项文件:
如果这样:
shell>mysql -u root –pmypass db_name>db_name.sql
或者这样在选项文件中提供参数:
[mysqldump]
user=root
password=mypass
然后执行
shell>mysqldump db_name>db_name.sql
那么一切顺利,不会有任何问题,但要注意命令历史会泄漏密码,或者不能让任何除 之外的用户能够访问选项文件,由于数据库服务器也需要这个选项文件时,选项文件只能被启动服务器的用户(如,mysql)拥有和访问,以免泄密。在unix下 还有一个解决办法,可以在自己的用户目录中提供个人选项文件(~/.my.cnf),例如,/home/some_user/.my.cnf,然后把上面的内容加入文件中,注意防止泄密。在nt系统中, 可以简单的让c:\my.cnf能被指定的用户访问。
可能要问,为什么这么麻烦呢,例如,这样使用命令行:
shell>mysql -u root –p db_name>db_name.sql
或者在选项文件中加入
[mysqldump]
user=root
password
然后执行命令行:
shell>mysql db_name>db_name.sql
发现了什么?往常熟悉的enter password:提示并没有出现,因为标准输出被重定向到文件db_name.sql中了,所以看不到往常的提示符,程序在等待 输入密码。在重定向的情况下,再使用交互模式,就会有问题。在上面的情况下, 还可以直接输入密码。然后在文件db_name.sql文件的第一行看到:
enter password:#……..
可能说问题不大,但是mysqldump之所以把结果输出到标准输出,是为了重定向到其它程序的标准输入,这样有利于编写脚本。例如:
用来自于一个数据库的信息充实另外一个mysql数据库也是有用的:
shell>mysqldump --opt database | mysql --host=remote-host -c database
如果mysqldump仍运行在提示输入密码的交互模式下,该命令不会成功,但是如果mysql是否运行在提示输入密码的交互模式下,都是可以的。
如果在选项文件中的[client]或者[mysqldump]任何一段中指定了password选项,且不提供密码,即使,在另一段中有提供密码的选项password=mypass,例如
[client]
user=root
password
[mysqldump]
user=admin
password=mypass
那么mysqldump一定要 输入admin用户的密码:
mysql>mysqldump db_name
即使是这样使用命令行:
mysql>mysqldump –u root –ppass1 db
也是这样,不过要如果-u指定的用户的密码。
其它使用选项文件的客户程序也是这样
3、有关生成sql语句的优化控制
--add-locks 生成的sql 语句中,在每个表数据恢复之前增加lock tables并且之后unlock table。(为了使得更快地插入到mysql)。
--add-drop-table 生成的sql 语句中,在每个create语句之前增加一个drop table。
-e, --extended-insert 使用全新多行insert语法。(给出更紧缩并且更快的插入语句)
下面两个选项能够加快备份表的速度:
-l, --lock-tables. 为开始导出数据前,读锁定所有涉及的表。
-q, --quick 不缓冲查询,直接倾倒至stdout。
理论上,备份时 应该指定上诉所有选项。这样会使命令行过于复杂,作为代替, 可以简单的指定一个--opt选项,它会使上述所有选项有效。
例如, 将导出一个很大的数据库:
shell> mysqldump --opt db_name > db_name.txt
当然,使用--tab选项时,由于不生成恢复数据的sql语句,使用--opt时,只会加快数据导出。
4、恢复mysqldump备份的数据
由于备份文件是sql语句的集合,所以需要在批处理模式下使用客户机
如果 使用mysqldump备份单个数据库或表,即:
shell>mysqldump --opt db_name > db_name.sql
由于db_name.sql中不包括创建数据库或者选取数据库的语句, 需要指定数据库
shell>mysql db2 < db_name.sql
如果, 使用--databases或者--all-databases选项,由于导出文件中已经包含创建和选用数据库的语句,可以直接使用,不比指定数据库,例如:
shell>mysqldump --databases db_name > db_name.sql
shell>mysql <db_name.sql
如果 使用--tab选项备份数据,数据恢复可能效率会高些
例如,备份数据库db_name后在恢复:
shell>mysqldump --tab=/path/to/dir --opt test
如果要恢复表的结构,可以这样:
shell>mysql < /path/to/dir/tbl1.sql
…
如果要恢复数据,可以这样
shell>mysqlimport -l db /path/to/dir/tbl1.txt
…
如果是在unix平台下使用(推荐),就更方便了:
shell>ls -l *.sql | mysql db
shell>mysqlimport --lock-tables db /path/to/dir/*.txt
三 .用直接拷贝的方法备份恢复
根据本章前两节的介绍,由于mysql的数据库和表是直接通过目录和表文件实现的,因此直接复制文件来备份数据库数据,对mysql来说特别方便。而且自mysql 3.23起myisam表成为缺省的表的类型,这种表可以为在不同的硬件体系中共享数据提供了保证。
使用直接拷贝的方法备份时,尤其要注意表没有被使用, 应该首先对表进行读锁定。
备份一个表,需要三个文件:
对于myisam表:
tbl_name.frm 表的描述文件
tbl_name.myd 表的数据文件
tbl_name.myi 表的索引文件
对于isam表:
tbl_name.frm 表的描述文件
tbl_name.isd 表的数据文件
tbl_name.ism 表的索引文件
直接拷贝文件从一个数据库服务器到另一个服务器,对于myisam表, 可以从运行在不同硬件系统的服务器之间复制文件
像 这个问题,可以把远程机器的mysql数据目录ftp下载到 本地的mysql目录下,重启mysql就可以了
- ixecfquvq | 2009-08-31 11:05:03
- 有0人认为这个回答不错 | 有0人认为这个回答没有帮助
- MySQL有很多可以导入数据的方法,然而这些只是数据传输中的一半,另外的一般是从MySQL数据库中导出数据。有许多的原因我们需要导出数据。一个重要的原因是用于备份数据库。数据的造价常常是昂贵的,需要谨慎处理它们。经常地备份可以帮助防止宝贵数据地丢失;另外一个原因是,也许您希望导出数据来共享。 在这个信息技术不断成长的世界中,共享数据变得越来越常见。
比方说Macmillan USA维护护着一个将要出版的书籍的大型数据库。这个数据库在许多书店之间共享,这样他们就知道哪些书将会很快出版。医院越来越走向采用无纸病历记录,这样这些病历可以随时跟着你。世界变得越来越小,信息也被共享得越来越多。有很多中导出数据得方法,它们都跟导入数据很相似。因为,毕竟,这些都只是一种透视得方式。从数据库导出的数据就是从另一端导入的数据。这里我们并不讨论其他的数据库各种各样的导出数据的方法,您将学会如何用MySQL来实现数据导出。
使用mysqldump:
(mysqldump命令位于mysql/bin/目录中)
mysqldump工具很多方面类似相反作用的工具mysqlimport。它们有一些同样的选项。但mysqldump能够做更多的事情。它可以把整个数据库装载到一个单独的文本文件中。这个文件包含有所有重建您的数据库所需要的SQL命令。这个命令取得所有的模式(Schema,后面有解释)并且将其转换成DDL语法(CREATE语句,即数据库定义语句),取得所有的数据,并且从这些数据中创建INSERT语句。这个工具将您的数据库中所有的设计倒转。因为所有的东西都被包含到了一个文本文件中。这个文本文件可以用一个简单的批处理和一个合适SQL语句导回到MySQL中。这个工具令人难以置信地简单而快速。决不会有半点让人头疼地地方。
因此,如果您像装载整个数据库Meet_A_Geek的内容到一个文件中,可以使用下面的命令:
bin/mysqldump –p Meet_A_Geek > MeetAGeek_Dump_File.txt
这个语句也允许您指定一个表进行dump(备份/导出/装载?)。如果您只是希望把数据库Meet_A_Geek中的表Orders中的整个内容导出到一个文件,可以使用下面的命令:
bin/mysqldump –p Meet_A_Geek Orders >MeetAGeek_Orders.txt
这个非常的灵活,您甚至可以使用WHERE从句来选择您需要的记录导出到文件中。要达到这样的目的,可以使用类似于下面的命令:
bin/mysqldump –p –where="Order_ID > 2000" Meet_A_Geek Orders > Special_Dump.txt
mysqldump工具有大量的选项,部分选项如下表:
选项/Option 作用/Action Performed
--add-drop-table
这个选项将会在每一个表的前面加上DROP TABLE IF EXISTS语句,这样可以保证导回MySQL数据库的时候不会出错,因为每次导回的时候,都会首先检查表是否存在,存在就删除
--add-locks
这个选项会在INSERT语句中捆上一个LOCK TABLE和UNLOCK TABLE语句。这就防止在这些记录被再次导入数据库时其他用户对表进行的操作
-c or - complete_insert
这个选项使得mysqldump命令给每一个产生INSERT语句加上列(field)的名字。当把数据导出导另外一个数据库时这个选项很有用。
--delayed-insert 在INSERT命令中加入DELAY选项
-F or -flush-logs 使用这个选项,在执行导出之前将会刷新MySQL服务器的log.
-f or -force 使用这个选项,即使有错误发生,仍然继续导出
--full 这个选项把附加信息也加到CREATE TABLE的语句中
-l or -lock-tables 使用这个选项,导出表的时候服务器将会给表加锁。
-t or -no-create- info
这个选项使的mysqldump命令不创建CREATE TABLE语句,这个选项在您只需要数据而不需要DDL(数据库定义语句)时很方便。
-d or -no-data 这个选项使的mysqldump命令不创建INSERT语句。
在您只需要DDL语句时,可以使用这个选项。
--opt 此选项将打开所有会提高文件导出速度和创造一个可以更快导入的文件的选项。
-q or -quick 这个选项使得MySQL不会把整个导出的内容读入内存再执行导出,而是在读到的时候就写入导文件中。
-T path or -tab = path 这个选项将会创建两个文件,一个文件包含DDL语句或者表创建语句,另一个文件包含数据。DDL文件被命名为table_name.sql,数据文件被命名为table_name.txt.路径名是存放这两个文件的目录。目录必须已经存在,并且命令的使用者有对文件的特权。
-w "WHERE Clause" or -where = "Where clause "
如前面所讲的,您可以使用这一选项来过筛选将要放到 导出文件的数据。
假定您需要为一个表单中要用到的帐号建立一个文件,经理要看今年(2004年)所有的订单(Orders),它们并不对DDL感兴趣,并且需要文件有逗号分隔,因为这样就很容易导入到Excel中。 为了完成这个人物,您可以使用下面的句子:
bin/mysqldump –p –where "Order_Date >='2000-01-01'"
–tab = /home/mark –no-create-info –fields-terminated-by=, Meet_A_Geek Orders
这将会得到您想要的结果。
schema:模式
The set of statements, expressed in data definition language, that completely describe the structure of a data base.
一组以数据定义语言来表达的语句集,该语句集完整地描述了数据库的结构。
SELECT INTO OUTFILE :
如果您觉得mysqldump工具不够酷,就使用SELECT INTO OUTFILE吧, MySQL同样提供一个跟LOAD DATA INFILE命令有相反作用的命令,这就是SELECT INTO OUTFILE 命令,这两个命令有很多的相似之处。首先,它们有所有的选项几乎相同。现在您需要完成前面用mysqldump完成的功能,可以依照下面的步骤进行操作:
1. 确保mysqld进程(服务)已经在运行
2. cd /usr/local/mysql
3. bin/mysqladmin ping ;// 如果这个句子通不过,可以用这个:mysqladmin -u root -p ping
mysqladmin ping用于检测mysqld的状态,is alive说明正在运行,出错则可能需要用户名和密码。
4. 启动MySQL 监听程序.
5. bin/mysql –p Meet_A_Geek;// 进入mysql命令行,并且打开数据库Meet_A_Geek,需要输入密码
6. 在命令行中,输入一下命令:
SELECT * INTO OUTFILE '/home/mark/Orders.txt'
FIELDS
TERMINATED BY = ','
FROM Orders
WHERE Order_Date >= '2000-01-01'
在你按了Return(回车)之后,文件就创建了。这个句子就像一个规则的SELECT语句,只是把想屏幕的输出重定向到了文件中。这意味这您可以使用JOIN来实现多表的高级查询。这个特点也可以被用作一个报表产生器。
比方说,您可以组合这一章中讨论的方法来产生一个非常有趣的查询,试试这个:
在mysql目录建立一个名为Report_G.rpt 的文本文件,加入下面的行:
USE Meet_A_Geek;
INSERT INTO Customers (Customer_ID, Last_Name, First_Name)
VALUES (NULL, "Kinnard", "Vicky");
INSERT INTO Customers (Customer_ID, Last_Name, First_Name)
VALUES (NULL, "Kinnard", "Steven");
INSERT INTO Customers (Customer_ID, Last_Name, First_Name)
VALUES (NULL, "Brown", "Sam");
SELECT Last_Name INTO OUTFILE '/home/mark/Report.rpt'
FROM Customers WHERE Customer_ID > 1;
然后确认 mysql进程在运行,并且您在mysql目录中, 输入下面的命令:
bin/mysql < Report_G.rpt检查您命名作为输出的文件,这个文件将会包含所有您在Customers表中输入的顾客的姓。 如您所见,您可以使用今天学到的导入/导出(import/export)的方法来帮助得到报表。