MYSQL数据库常用知识整理

MYSQL数据库常用知识整理

  • 什么是MYSQL

  • MYSQL的特性

  • MYSQL存储引擎的分类以及数据文件的介绍

  • MYSQL赋权

  • MYSQL备份与恢复

  • MYSQL的基本操作:增删查改

  • MYSQL的基本故障判断与处理

  • MYSQL的调优

  • MYSQL主主、主从复制的实现

  • MYSQL大数据备份和恢复

  • 数据文件的损坏与修复

什么是MYSQL

MySQL是一个开放源码的小型关联式数据库管理系统,开发者为瑞典MySQL AB公司。目前MySQL被广泛地应用在Internet上的中小型网站中。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。

MYSQL的特性

  • 使用C和C++编写,并使用了多种编译器进行测试,保证源代码的可移植性。

  • 支持AIX、BSDi、FreeBSD、HP-UX、Linux、Mac OS、Novell Netware、NetBSD、OpenBSD、OS/2 Wrap、Solaris、SunOS、Windows等多种操作系统。

  • 为多种编程语言提供了API。这些编程语言包括C、C++、C#、Delphi、Eiffel、Java、Perl、PHP、Python、Ruby和Tcl等。

  • 支持多线程,充分利用CPU资源,支持多用户。

  • 优化的SQL查询算法,有效地提高查询速度。

  • 既能够作为一个单独的应用程序应用在客户端服务器网络环境中,也能够作为一个库而嵌入到其他的软件中。

  • 提供多语言支持,常见的编码如中文的GB 2312、BIG5,日文的Shift_JIS等都可以用作数据表名和数据列名。

  • 提供TCP/IP、ODBC和JDBC等多种数据库连接途径。

  • 提供用于管理、检查、优化数据库操作的管理工具。

  • 可以处理拥有上千万条记录的大型数据库。

MYSQL存储引擎的分类以及数据文件的介绍

一、安装与部署、配置文件的介绍

①安装简介

源码编译安装,请大家自己亲自动手编译安装。

(了解不同版本的区别尤其是5.5和5.6)

②配置文件说明

basedir = path 使用给定目录作为根目录(安装目录)。
character-sets-dir = path 给出存放着字符集的目录。
datadir = path 从给定目录读取数据库文件。
pid-file = filename 为mysqld程序指定一个存放进程ID的文件(仅适用于UNIX/Linux系统); Init-V脚本需要使用这个文件里的进程ID结束mysqld进程。
socket = filename 为MySQL客户程序与服务器之间的本地通信指定一个套接字文件(仅适用于UNIX/Linux系统; 默认设置一般是/var/lib/mysql/mysql.sock文件)。在Windows环境下,如果MySQL客户与服务器是通过命名管道进行通信 的,–sock选项给出的将是该命名管道的名字(默认设置是MySQL)。
lower_case_table_name = 1/0 新目录和数据表的名字是否只允许使用小写字母; 这个选项在Windows环境下的默认设置是1(只允许使用小写字母)。

 

mysqld程序:语言设置

character-sets-server = name 新数据库或数据表的默认字符集。为了与MySQL的早期版本保持兼容,这个字符集也可以用–default-character-set选项给出; 但这个选项已经显得有点过时了。
collation-server = name 新数据库或数据表的默认排序方式。
lanuage = name 用指定的语言显示出错信息。

 

mysqld程序:通信、网络、信息安全

enable-named-pipes 允许Windows 2000/XP环境下的客户和服务器使用命名管道(named pipe)进行通信。这个命名管道的默认名字是MySQL,但可以用–socket选项来改变。
local-infile [=0] 允许/禁止使用LOAD DATA LOCAL语句来处理本地文件。
myisam-recover [=opt1, opt2, ...] 在启动时自动修复所有受损的MyISAM数据表。这个选项的可取值有4种:DEFAULT、BACKUP、QUICK和FORCE; 它们与myisamchk程序的同名选项作用相同。
old-passwords 使用MySQL 3.23和4.0版本中的老算法来加密mysql数据库里的密码(默认使用MySQL 4.1版本开始引入的新加密算法)。
port = n 为MySQL程序指定一个TCP/IP通信端口(通常是3306端口)。
safe-user-create 只有在mysql.user数据库表上拥有INSERT权限的用户才能使用GRANT命令; 这是一种双保险机制(此用户还必须具备GRANT权限才能执行GRANT命令)。
shared-memory 允许使用内存(shared memory)进行通信(仅适用于Windows)。
shared-memory-base-name = name 给共享内存块起一个名字(默认的名字是MySQL)。
skip-grant-tables 不使用mysql数据库里的信息来进行访问控制(警告:这将允许用户任何用户去修改任何数据库)。
skip-host-cache 不使用高速缓存区来存放主机名和IP地址的对应关系。
skip-name-resovle 不把IP地址解析为主机名; 与访问控制(mysql.user数据表)有关的检查全部通过IP地址行进。
skip-networking 只允许通过一个套接字文件(Unix/Linux系统)或通过命名管道(Windows系统)进行本地连接,不允许ICP/IP连接; 这提高了安全性,但阻断了来自网络的外部连接和所有的Java客户程序(Java客户即使在本地连接里也使用TCP/IP)。
user = name mysqld程序在启动后将在给定UNIX/Linux账户下执行; mysqld必须从root账户启动才能在启动后切换到另一个账户下执行; mysqld_safe脚本将默认使用–user=mysql选项来启动mysqld程序。

 

mysqld程序:内存管理、优化、查询缓存区

bulk_insert_buffer_size = n 为一次插入多条新记录的INSERT命令分配的缓存区长度(默认设置是8M)。
key_buffer_size = n 用来存放索引区块的RMA值(默认设置是8M)。
join_buffer_size = n 在参加JOIN操作的数据列没有索引时为JOIN操作分配的缓存区长度(默认设置是128K)。
max_heap_table_size = n HEAP数据表的最大长度(默认设置是16M); 超过这个长度的HEAP数据表将被存入一个临时文件而不是驻留在内存里。
max_connections = n MySQL服务器同时处理的数据库连接的最大数量(默认设置是100)。
query_cache_limit = n 允许临时存放在查询缓存区里的查询结果的最大长度(默认设置是1M)。
query_cache_size = n 查询缓存区的最大长度(默认设置是0,不开辟查询缓存区)。
query_cache_type = 0/1/2 查询缓存区的工作模式:0, 禁用查询缓存区; 1,启用查询缓存区(默认设置); 2,”按需分配”模式,只响应SELECT SQL_CACHE命令。
read_buffer_size = n 为从数据表顺序读取数据的读操作保留的缓存区的长度(默认设置是128KB); 这个选项的设置值在必要时可以用SQL命令SET SESSION read_buffer_size = n命令加以改变。
read_rnd_buffer_size = n 类似于read_buffer_size选项,但针对的是按某种特定顺序(比如使用了ORDER BY子句的查询)输出的查询结果(默认设置是256K)。
sore_buffer = n 为排序操作分配的缓存区的长度(默认设置是2M); 如果这个缓存区太小,则必须创建一个临时文件来进行排序。
table_cache = n 同时打开的数据表的数量(默认设置是64)。
tmp_table_size = n 临时HEAP数据表的最大长度(默认设置是32M); 超过这个长度的临时数据表将被转换为MyISAM数据表并存入一个临时文件。

 

mysqld程序:日志

log [= file] 把所有的连接以及所有的SQL命令记入日志(通用查询日志); 如果没有给出file参数,MySQL将在数据库目录里创建一个hostname.log文件作为这种日志文件(hostname是服务器的主机名)。
log-slow-queries [= file] 把执行用时超过long_query_time变量值的查询命令记入日志(慢查询日志); 如果没有给出file参数,MySQL将在数据库目录里创建一个hostname-slow.log文件作为这种日志文件(hostname是服务器主机 名)。
long_query_time = n 慢查询的执行用时上限(默认设置是10s)。
long_queries_not_using_indexs 把慢查询以及执行时没有使用索引的查询命令全都记入日志(其余同–log-slow-queries选项)。
log-bin [= filename] 把对数据进行修改的所有SQL命令(也就是INSERT、UPDATE和DELETE命令)以二进制格式记入日志(二进制变更日志,binary update log)。这种日志的文件名是filename.n或默认的hostname.n,其中n是一个6位数字的整数(日志文件按顺序编号)。
log-bin-index = filename 二进制日志功能的索引文件名。在默认情况下,这个索引文件与二进制日志文件的名字相同,但后缀名是.index而不是.nnnnnn。
max_binlog_size = n 二进制日志文件的最大长度(默认设置是1GB)。在前一个二进制日志文件里的信息量超过这个最大长度之前,MySQL服务器会自动提供一个新的二进制日志文件接续上。
binlog-do-db = dbname 只把给定数 据库里的变化情况记入二进制日志文件,其他数据库里的变化情况不记载。如果需要记载多个数据库里的变化情况,就必须在配置文件使用多个本选项来设置,每个数据库一行。
binlog-ignore-db = dbname 不把给定数据库里的变化情况记入二进制日志文件。
sync_binlog = n 每经过n次日志写操作就把日志文件写入硬盘一次(对日志信息进行一次同步)。n=1是最安全的做法,但效率最低。默认设置是n=0,意思是由操作系统来负责二进制日志文件的同步工作。
log-update [= file] 记载出错情况的日志文件名(出错日志)。这种日志功能无法禁用。如果没有给出file参数,MySQL会使用hostname.err作为种日志文件的名字。

 

mysqld程序:镜像(主控镜像服务器)

server-id = n 给服务器分配一个独一无二的ID编号; n的取值范围是1~2的32次方启用二进制日志功能。
log-bin = name 启用二进制日志功能。这种日志的文件名是filename.n或默认的hostname.n,其中的n是一个6位数字的整数(日志文件顺序编号)。
binlog-do/ignore-db = dbname 只把给定数据库里的变化情况记入二进制日志文件/不把给定的数据库里的变化记入二进制日志文件。

 

mysqld程序:镜像(从属镜像服务器)

server-id = n 给服务器分配一个唯一的ID编号
log-slave-updates 启用从属服务器上的日志功能,使这台计算机可以用来构成一个镜像链(A->B->C)。
master-host = hostname 主控服务器的主机名或IP地址。如果从属服务器上存在mater.info文件(镜像关系定义文件),它将忽略此选项。
master-user = replicusername 从属服务器用来连接主控服务器的用户名。如果从属服务器上存在mater.info文件,它将忽略此选项。
master-password = passwd 从属服务器用来连接主控服务器的密码。如果从属服务器上存在mater.info文件,它将忽略此选项。
master-port = n 从属服务器用来连接主控服务器的TCP/IP端口(默认设置是3306端口)。
master-connect-retry = n 如果与主控服务器的连接没有成功,则等待n秒(s)后再进行管理方式(默认设置是60s)。如果从属服务器存在mater.info文件,它将忽略此选项。
master-ssl-xxx = xxx 对主、从服务器之间的SSL通信进行配置。
read-only = 0/1 0: 允许从属服务器独立地执行SQL命令(默认设置); 1: 从属服务器只能执行来自主控服务器的SQL命令。
read-log-purge = 0/1 1: 把处理完的SQL命令立刻从中继日志文件里删除(默认设置); 0: 不把处理完的SQL命令立刻从中继日志文件里删除。
replicate-do-table = dbname.tablename 与–replicate-do-table选项的含义和用法相同,但数据库和数据库表名字里允许出现通配符”%” (例如: test%.%–对名字以”test”开头的所有数据库里的所以数据库表进行镜像处理)。

 

replicate-do-db = name 只对这个数据库进行镜像处理。
replicate-ignore-table = dbname.tablename 不对这个数据表进行镜像处理。
replicate-wild-ignore-table = dbn.tablen 不对这些数据表进行镜像处理。
replicate-ignore-db = dbname 不对这个数据库进行镜像处理。
replicate-rewrite-db = db1name > db2name 把主控数据库上的db1name数据库镜像处理为从属服务器上的db2name数据库。
report-host = hostname 从属服务器的主机名; 这项信息只与SHOW SLAVE HOSTS命令有关–主控服务器可以用这条命令生成一份从属服务器的名单。
slave-compressed-protocol = 1 主、从服务器使用压缩格式进行通信–如果它们都支持这么做的话。
slave-skip-errors = n1, n2, …或all 即使发生出错代码为n1、n2等的错误,镜像处理工作也继续进行(即不管发生什么错误,镜像处理工作也继续进行)。如果配置得当,从属服务器不应该在执行 SQL命令时发生错误(在主控服务器上执行出错的SQL命令不会被发送到从属服务器上做镜像处理); 如果不使用slave-skip-errors选项,从属服务器上的镜像工作就可能因为发生错误而中断,中断后需要有人工参与才能继续进行。

 

mysqld–InnoDB:基本设置、表空间文件

skip-innodb 不加载InnoDB数据表驱动程序–如果用不着InnoDB数据表,可以用这个选项节省一些内存。
innodb-file-per-table 为每一个新数据表创建一个表空间文件而不是把数据表都集中保存在中央表空间里(后者是默认设置)。该选项始见于MySQL 4.1。
innodb-open-file = n InnoDB数据表驱动程序最多可以同时打开的文件数(默认设置是300)。如果使用了innodb-file-per-table选项并且需要同时打开很多数据表的话,这个数字很可能需要加大。
innodb_data_home_dir = p InnoDB主目录,所有与InnoDB数据表有关的目录或文件路径都相对于这个路径。在默认的情况下,这个主目录就是MySQL的数据目录。
innodb_data_file_path = ts 用来容纳InnoDB为数据表的表空间: 可能涉及一个以上的文件; 每一个表空间文件的最大长度都必须以字节(B)、兆字节(MB)或千兆字节(GB)为单位给出; 表空间文件的名字必须以分号隔开; 最后一个表空间文件还可以带一个autoextend属性和一个最大长度(max:n)。例如,ibdata1:1G; ibdata2:1G:autoextend:max:2G的意思是: 表空间文件ibdata1的最大长度是1GB,ibdata2的最大长度也是1G,但允许它扩充到2GB。除文件名外,还可以用硬盘分区的设置名来定义表 空间,此时必须给表空间的最大初始长度值加上newraw关键字做后缀,给表空间的最大扩充长度值加上raw关键字做后缀(例如/dev/hdb1: 20Gnewraw或/dev/hdb1:20Graw); MySQL 4.0及更高版本的默认设置是ibdata1:10M:autoextend。
innodb_autoextend_increment = n 带有autoextend属性的表空间文件每次加大多少兆字节(默认设置是8MB)。这个属性不涉及具体的数据表文件,那些文件的增大速度相对是比较小的。
innodb_lock_wait_timeout = n 如果某个事务在等待n秒(s)后还没有获得所需要的资源,就使用ROLLBACK命令放弃这个事务。这项设置对于发现和处理未能被InnoDB数据表驱动 程序识别出来的死锁条件有着重要的意义。这个选项的默认设置是50s。
innodb_fast_shutdown 0/1 是否以最快的速度关闭InnoDB,默认设置是1,意思是不把缓存在INSERT缓存区的数据写入数据表,那些数据将在MySQL服务器下次启动时再写入 (这么做没有什么风险,因为INSERT缓存区是表空间的一个组成部分,数据不会丢失)。把这个选项设置为0反面危险,因为在计算机关闭时,InnoDB 驱动程序很可能没有足够的时间完成它的数据同步工作,操作系统也许会在它完成数据同步工作之前强行结束InnoDB,而这会导致数据不完整。

 

mysqld程序:InnoDB–日志

innodb_log_group_home_dir = p 用来存放InnoDB日志文件的目录路径(如ib_logfile0、ib_logfile1等)。在默认的情况下,InnoDB驱动程序将使用 MySQL数据目录作为自己保存日志文件的位置。
innodb_log_files_in_group = n 使用多少个日志文件(默认设置是2)。InnoDB数据表驱动程序将以轮转方式依次填写这些文件; 当所有的日志文件都写满以后,之后的日志信息将写入第一个日志文件的最大长度(默认设置是5MB)。这个长度必须以MB(兆字节)或GB(千兆字节)为单 位进行设置。
innodb_flush_log_at_trx_commit = 0/1/2 这个选项决定着什么时候把日志信息写入日志文件以及什么时候把这些文件物理地写(术语称为”同步”)到硬盘上。设置值0的意思是每隔一秒写一次日志并进行 同步,这可以减少硬盘写操作次数,但可能造成数据丢失; 设置值1(设置设置)的意思是在每执行完一条COMMIT命令就写一次日志并进行同步,这可以防止数据丢失,但硬盘写操作可能会很频繁; 设置值2是一般折衷的办法,即每执行完一条COMMIT命令写一次日志,每隔一秒进行一次同步。
innodb_flush_method = x InnoDB日志文件的同步办法(仅适用于UNIX/Linux系统)。这个选项的可取值有两种: fdatasync,用fsync()函数进行同步; O_DSYNC,用O_SYNC()函数进行同步。
innodb_log_archive = 1 启用InnoDB驱动程序的archive(档案)日志功能,把日志信息写入ib_arch_log_n文件。启用这种日志功能在InnoDB与 MySQL一起使用时没有多大意义(启用MySQL服务器的二进制日志功能就足够用了)。

 

mysqld程序–InnoDB:缓存区的设置和优化

innodb_log_buffer_pool_size = n 为InnoDB数据表及其索引而保留的RAM内存量(默认设置是8MB)。这个参数对速度有着相当大的影响,如果计算机上只运行有 MySQL/InnoDB数据库服务器,就应该把全部内存的80%用于这个用途。

 

innodb_log_buffer_size = n 事务日志文件写操作缓存区的最大长度(默认设置是1MB)。
innodb_additional_men_pool_size = n 为用于内部管理的各种数据结构分配的缓存区最大长度(默认设置是1MB)。
innodb_file_io_threads = n I/O操作(硬盘写操作)的最大线程个数(默认设置是4)。
innodb_thread_concurrency = n InnoDB驱动程序能够同时使用的最大线程个数(默认设置是8)。

 

mysqld程序:其它选项

bind-address = ipaddr MySQL服务器的IP地址。如果MySQL服务器所在的计算机有多个IP地址,这个选项将非常重要。
default-storage-engine = type 新数据表的默认数据表类型(默认设置是MyISAM)。这项设置还可以通过–default-table-type选项来设置。
default-timezone = name 为MySQL服务器设置一个地理时区(如果它与本地计算机的地理时区不一样)。
ft_min_word_len = n 全文索引的最小单词长度工。这个选项的默认设置是4,意思是在创建全文索引时不考虑那些由3个或更少的字符构建单词。
Max-allowed-packet = n 客户与服务器之间交换的数据包的最大长度,这个数字至少应该大于客户程序将要处理的最大BLOB块的长度。这个选项的默认设置是1MB。
Sql-mode = model1, mode2, … MySQL将运行在哪一种SQL模式下。这个选项的作用是让MySQL与其他的数据库系统保持最大程度的兼容。这个选项的可取值包括ansi、db2、 oracle、no_zero_date、pipes_as_concat。




③启动脚本



二、MYSQL存储引擎的分类: MYISAM  INNODB


myISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。与其他存储引擎比较,MyISAM具有检查和修复表格的大多数工具。 MyISAM表格可以被压缩,而且它们支持全文搜索。它们不是事务安全的,而且也不支持外键。如果事物回滚将造成不完全回滚,不具有原子性。如果执行大量的SELECT,MyISAM是更好的选择。

MyIASM是IASM表的新版本,有如下扩展:

  • 二进制层次的可移植性。

  • NULL列索引。

  • 对变长行比ISAM表有更少的碎片。

  • 支持大文件。

  • 更好的索引压缩。

  • 更好的键吗统计分布。

  • 更好和更快的auto_increment处理。

InnoDB:这种类型是事务安全的。它与BDB类型具有相同的特性,它们还支持外键。InnoDB表格速度很快,具有比BDB还丰富的特性, 因此如果需要一个事务安全的存储引擎,建议使用它。如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。对 于支持事物的InnoDB类型的表,影响速度的主要原因是AUTOCOMMIT默认设置是打开的,而且程序没有显式调用BEGIN 开始事务,导致每插入一条都自动Commit,严重影响了速度。可以在执行sql前调用begin,多条sql形成一个事物(即使autocommit打 开也可以),将大大提高性能。

具体可以看看下表:


MyISAM InnoDB
构成上区别

每个MyISAM在磁盘上存储成三个文件。文件名为表名,扩展名为文件类型。

.frm 文件存储表定义;
.MYD(MYData) 数据文件的扩展名;
.MYI(MYIndex) 索引文件的扩展名。
基于磁盘的资源是InnoDB表空间数据文件和它的日志文件,InnoDB 表的大小只受限于操作系统文件的大小,一般为 2GB
事务处理方面 MyISAM类型的表强调的是性能,其执行速度比InnoDB类型更快,但是不提供事务支持。

InnoDB提供事务支持事务,外部键等高级数据库功能。

表级锁

行级锁

InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如update table set num=1 where name like “%aaa%”

select、insert、update、delete操作 如果执行大量的 SELECT,MyISAM 是更好的选择。

1.如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。

2.DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。

3.LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用。

对于AUTO_INCREMENT类型的字段 必须包含只有该字段的索引 可以和其他字段一起建立联合索引


InnoDB不支持FULLTEXT类型的索引。

MyISAM类型的二进制数据文件可以在不同操作系统中迁移


以下是一些细节和具体实现的差别:

  1. InnoDB不支持FULLTEXT类型的索引。

  2. InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。

  3. 对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。

  4. DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。

  5. LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用。

综上所述,任何一种表都不是万能的,只有恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。

二、MYSQL数据文件的介绍

一、MySQL数据库文件介绍

MySQL的每个数据库都对应存放在一个与数据库同名的文件夹中,MySQL数据库文件包括MySQL所建数据库文件和MySQL所用存储引擎创建的数据库文件。

1、MySQL创建并管理的数据库文件:

.frm文件:存储数据表的框架结构,文件名与表名相同,每个表对应一个同名frm文件,与操作系统和存储引擎无关,即不管MySQL运行在何种操作系统上,使用何种存储引擎,都有这个文件。

除了必有的.frm文件,根据MySQL所使用的存储引擎的不同(MySQL常用的两个存储引擎是MyISAM和InnoDB),存储引擎会创建各自不同的数据库文件。

2、MyISAM数据库表文件:

.MYD文件:即MY Data,表数据文件

.MYI文件:即MY Index,索引文件

.log文件:日志文件

3、InnoDB采用表空间(tablespace)来管理数据,存储表数据和索引,

InnoDB数据库文件(即InnoDB文件集,ib-file set):

ibdata1、ibdata2等:系统表空间文件,存储InnoDB系统信息和用户数据库表数据和索引,所有表共用

.ibd文件:单表表空间文件,每个表使用一个表空间文件(file per table),存放用户数据库表数据和索引

日志文件: ib_logfile1、ib_logfile2

二、MySQL数据库存放位置:

1、MySQL如果使用MyISAM存储引擎,数据库文件类型就包括.frm、.MYD、.MYI,默认存放位置是C:\Documentsand Settings\All Users\Application Data\MySQL\MySQL Server 5.1\data

2、MySQL如果使用InnoDB存储引擎,数据库文件类型就包括.frm、ibdata1、.ibd,存放位置有两个,

.frm文件默认存放位置是C:\Documents and Settings\All Users\ApplicationData\MySQL\MySQL Server 5.1\data,ibdata1、.ibd文件默认存放位置是MySQL安装目录下的data文件夹



三、MYSQL赋权


#给用户cacti赋予所有库的所有权限
GRANT ALL PRIVILEGES ON *.* TO 'cacti'@'%' IDENTIFIED BY 'cacti' WITH GRANT OPTION;
#重新载入赋权表
FLUSH PRIVILEGES;

#收回权限(不包含赋权权限)
REVOKE ALL PRIVILEGES ON *.* FROM cacti;
REVOKE ALL PRIVILEGES ON cacti.* FROM cacti;
#收回赋权权限
REVOKE GRANT OPTION ON *.* FROM cacti;
#重新载入赋权表
FLUSH PRIVILEGES;


#查看赋权权限

show grants for 'cacti'@'%' 


四、MYSQL备份与恢复



一:实验环境介绍:

系统介绍:CentOS6.4_X64

数据库版本:mysql-5.5.33


二:基于Mysqldump命令实现备份恢复

2.1、思路概念

   Mysqldump是一个逻辑备份命令;意思就是将数据库中的数据备份成一个文本文件;也可以说是将表的结构和数据存储在文本文件中。

   Mysqldump命令的工作原理很简单,它先查出需要备份的表的结构,再在文本文件中生成一个CREATE语句。然后,将表中的所有记录转换为一条INSTERT语句。这些CREATE语句和INSTERT语句都是还原时使用的。还原数据时就可以使用其中的CREATE语句来创建表。使用其中的INSERT语句来还原数据。它可以实现整个服务器备份,也可以实现单个或部分数据库、单个或部分表、表中的某些行、存储过程、存储函数、触发器的备份;并且能自动记录备份时刻的二进制日志文件及相应的位置。对于InnoDB存储引擎来讲支持基于单事务模式实现热备,对于MyISAM则最多支持温备。

2.2、备份策略

  Mysqldump全备+二进制日志增备

2.3、过程实现

(1)Mysqldump全备

     由于Mysql数据库默认的为MyISAM存储引擎所以只有使用温备(备份同时仅支持读请求)进行,所以我们要为所有数据库添加读锁

1

[root@stu18 ~]                 #mysqldump -uroot -pmypass --lock-all-tables --master-data=2 --events --routines--all-databases > /zhao/database_`date +%F`.sql

   解析:--lock-all-tables表示为所有表施加读锁;--master-data=2表示在备份文件中记录当前二进制日志的位置;--events表示备份数据的同时备份时间调度器代码;--routines表示备份数据的同时备份存储过程和存储函数;--all-databases表示备份所有库。

1

2

3

4

5

6

7

8

9

[root@stu18 zhao]                 # less database_2013-08-13.sql

--                             #表示注释项

-- Position to start replication or point-                 in                 -                 time                  recovery from

--

-- CHANGE MASTER TO MASTER_LOG_FILE=                 'mysql-bin.000001'                 , MASTER_LOG_POS=14203;                   #这里表示当前处于mysql-bin.000001这个二进制日志中,事件为14203这是通过--master-data=2产生的

--

-- Current Database: `hellodb`

--

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `hellodb` /*!40100 DEFAULT CHARACTER SET utf8 */;

(2)二进制全备

   方法一: 导出二进制日志文件内容

1

[root@stu18 data]                 # mysqlbinlog mysql-bin.000001 >/zhao/binlog_`date +%F`.sql

   方法二:滚动日志复制文件

1

2

mysql> flush logs;                                 #滚动日志

[root@stu18 data]                 # cp mysql-bin.000001 /zhao/mysql-bin.000001 #复制导出二进制文件

(3)二进制增备

   首先添加数据信息

1

2

mysql> use hellodb;

mysql> INSERT INTO students(Name,Age,Gender,ClassID,TeacherID) values (                 'Yang kang'                ,22,                 'M'                 ,3,3);

   然后二进制增备

1

[root@stu18 data]                 # mysqlbinlog --start-position=14203 --stop-position=14527 mysql-bin.000001 > /zhao/binlog_`date +%F_%H`.sql

   解析:--start-position=14203是上次全备之后的二进制事件位置;--stop-position=14527最近一天的二进制事件位置。

2.4、模拟数据库损坏,实现恢复工作

1

2

3

4

5

6

7

8

mysql> DROP DATABASE hellodb;                              #删除数据库

############下面这些过程要在离线状态下执行############

mysql> SET sql_log_bin=0;                                  #先关闭二进制日志

mysql> flush logs;                                         #滚动日志

[root@stu18 ~]                 # mysql -uroot -pmypass < /zhao/database_2013-08-13.sql  #导入数据库备份文件

[root@stu18 ~]                 # mysql -uroot -pmypass < /zhao/binlog_2013-08-13_19.sql #导入增量备份文件

[root@stu18 ~]                 # mysql -uroot –pmypass    #登录查看,恢复完成

mysql> SET sql_log_bin=1;                                  #开启二进制日志

   这种备份方式恢复简单,但是恢复还原之后索引会出现错误需要重建,而且备份结果会占据很大的空间,请酌情使用。


三、基于LVM快照实现备份恢复

3.1、思路明细

(1)LVM这种备份方式要求Mysql的数据保存在逻辑卷上

(2)需要给Mysql服务器施加读锁(mysql>FLUSH TABLES WITH READLOCK;),这里不可直接退出服务器

(3)另起终端为数据所在的卷创建快照(lvcreate),保证事务日志和数据文件必须在同一卷上(分别创建可能会导致数据文件和事务日志不一致,从而可能导致无法正常恢复)

3.2、备份策略

 LVM快照全备+二进制日志增备(对于即时点恢复还要恢复至后续的二进制位置)

3.3、前提条件

 (1)创建逻辑卷及挂载逻辑卷,此过程在此就不做演示了可参考博文

          http://pangge.blog.51cto.com/6013757/1256568

 (2)初始化mysql将其数据目录指向/mydata/data

1

2

[root@stu18 ~]                 # cd /usr/local/mysql/

[root@stu18 mysql]                 # scripts/mysql_install_db --user=mysql --datadir=/mydata/data

 (3)编辑查看配置文件,重启服务

1

2

3

4

[root@stu18 mysql]                 # vim /etc/my.cnf

datadir =                  /mydata/data                         #查看此项是否定义数据目录位置

sync_binlog=1                                  #添加此项,每个事务提交时候,把事务日志从缓存区写到日志文件中,并且刷新日志文件的数据到磁盘上;

[root@stu18 mysql]                 # service mysqld start

3.4、过程展示

 (1)确保事务日志和数据文件必须在同一卷上

1

2

3

4

5

[root@stu18 ~]                 # ls /mydata/data/

hellodb      myclass           mysql-bin.000003    stu18.magedu.com.err

ibdata1      mysql             mysql-bin.000004    stu18.magedu.com.pid

ib_logfile0  mysql-bin.000001  mysql-bin.index     student

ib_logfile1  mysql-bin.000002  performance_schema                   test

 解析:其中ib_logfile0与ib_logfile1是日志文件

 (2)施加全局锁并滚动日志

1

2

mysql> FLUSH TABLES WITH READ LOCK;

mysql> FLUSH LOGS;

 (3)查看并保存当前正在使用的二进制日志及当前执行二进制日志位置(非常重要)

1

2

3

4

5

6

7

mysql> SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000004 |      187 |              |                  |

+------------------+----------+--------------+------------------+

[root@stu18 zhao]                 # mysql -uroot -pmypass -e 'SHOW MASTER STATUS;' >/zhao/lvmback-2013-08-14/binlog.txt

 (4)创建快照卷

1

[root@stu18 zhao]                 # lvcreate -L 100M -s -p r -n mydata-lvm /dev/vg1/mydata

 (5)立即切换终端释放锁

1

mysql> UNLOCK TABLES;

 (6)备份数据

1

[root@stu18 data]                 # cp -a * /zhao/lvmback-2013-08-14/

 (7)二进制实现增量备份

1

2

3

4

5

6

7

mysql> use hellodb;                            #指定默认数据库

Database changed

mysql> CREATE TABLE testtb (                 id                  int,name CHAR(10));                      #创建表

Query OK, 0 rows affected (0.35 sec)

mysql> INSERT INTO testtb VALUES (1,                 'tom'                 );                             #添加数据

Query OK, 1 row affected (0.09 sec)

[root@stu18 data]                 # mysqlbinlog --start-position=187 mysql-bin.000004 > /zhao/lvmlogbin_2013-08-14/binlog.sql            #日志实现增量备份

 (8)模拟数据库崩溃

1

2

3

[root@stu18 ~]                 # service mysqld stop

[root@stu18 ~]                 # cd /mydata/data/

[root@stu18 data]                 # rm -rf *

 (9)恢复数据

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

[root@stu18 ~]                 # cp /zhao/lvmback-2013-08-14/* /mydata/data/ -a          #完全备份恢复

[root@stu18 ~]                 # cd /mydata/data/             #查看恢复数据内容

[root@stu18 data]                 # chown -R mysql.mysql *    #更改属主属组

[root@stu18 data]                 # service mysqld start      #启动服务

[root@stu18 data]                 # mysql -uroot –pmypass    #登录测试

mysql> SHOW DATABASES;                       #查看数据完整性,无测试表testtd使用二进制恢复

mysql> SET sql_log_bin=0                     #关闭二进制日志

mysql>                  source                  /zhao/lvmlogbin_2013-08-14/binlog                 .sql;                  #二进制恢复

mysql> SHOW TABLES;                          #查看恢复结果

+-------------------+

| Tables_in_hellodb |

+-------------------+

| classes           |

| coc               |

| courses           |

| scores            |

| students          |

| teachers          |

| testtb            |

| toc               |

+-------------------+

mysql> SET sql_log_bin=1;                    #开启二进制日志


此工具是接近于热备的方式实现的,并且用此方法来备份恢复数据速度是非常快的。


四:基于xtrabackup来实现备份恢复

4.1、优势特性

   完全以热备的形式进行,能够实现快速可靠地完全备份和部分备份,支持增量备份,支持时间点还原,备份过程中不会打扰到事务操作,能够实现网络传输和压缩功能从而有效的节约磁盘空间,备份完成后可自动验证数据是否可用,恢复速度较快等等。更多优势特性请参考http://www.percona.com/software/percona-xtrabackup

注意:以上这些优势特性只能在InnoDB引擎上完美实现,而在MyISAM存储引擎上依然最多只能使用温备的形式进行并且还不支持增量备份。

另外Xtrabackup更多的高级功能还依赖于Mysql数据库对于InnoDB实现了单独的表空间,否则也就没有办法实现单表导入导出查看方式如下:

1

2

3

4

5

6

7

8

9

mysql> SHOW GLOBAL VARIABLES LIKE                  'innodb_file%'                 ;

+--------------------------+----------+

| Variable_name            | Value    |

+--------------------------+----------+

| innodb_file_format       | Antelope |

| innodb_file_format_check | ON       |

| innodb_file_format_max   | Antelope |

| innodb_file_per_table    | ON      |

+--------------------------+----------+

   其中的innodb_file_per_table为ON则表示实现了单表单空间。若为OFF则需要使用mysqldump全备然后更改配置文件删除原来的数据文件并重新初始化服务器最后将数据重新导入。所以建议以后在安装Mysql服务器时将其选项默认设置成1即可(innodb_file_per_table = 1)。单表单空间的数据显示形式为:

1

2

3

4

5

[root@stu18 hellodb]                 # ls

classes.frm  coc.MYD      courses.MYI  scores.MYI    teachers.frm  testtb.ibd

classes.MYD  coc.MYI      db.opt       students.frm  teachers.MYD  toc.frm

classes.MYI  courses.frm  scores.frm   students.MYD  teachers.MYI  toc.MYD

coc.frm      courses.MYD  scores.MYD   students.MYI  testtb.frm    toc.MYI

4.2、安装Xtrabackup

 下载percona-xtrabackup最新的版本为2.1.4(percona-xtrabackup-2.1.4-656.rhel6.x86_64.rpm)

   安装:

1

[root@stu18 ~]# rpm -ivh percona-xtrabackup-                 2.1                 .                 4                 -               656                 .rhel6.x86_64.rpm

   若有错误无法安装请安装perl-DBD-mysql依赖包

1

[root@stu18 ~]# yum -y install perl-DBD-mysql

    注意:不同的环境依赖的关系包可能有多个,请依照提示进行配置

4.3、完全备份

   使用innobakupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命令的目录中。完全备份命令如下:

1

# innobackupex --user=DBUSER--password=DBUSERPASS /path/to/BACKUP-DIR/

  实现过程及说明:

1

2

3

4

5

6

7

8

9

[root@stu18 ~]                 # mkdir /innobackup              #创建备份文件目录

[root@stu18 ~]                 # innobackupex --user=root --password=mypass /innobackup/    #完全备份

################如果执行正确其后输出的几行信息通常如下###############

xtrabackup: Transaction log of lsn (1604655) to (1604655) was copied.                  #二进制日志的位置(lsn)

130814 07:04:55  innobackupex: All tables unlocked

innobackupex: Backup created                  in                  directory                  '/innobackup/2013-08-14_07-04-49'                 #备份文件保存的位置

innobackupex: MySQL binlog position: filename                  'mysql-bin.000003'                 , position 538898

130814 07:04:55  innobackupex: Connection to database server closed

130814 07:04:55  innobackupex: completed OK!       备份完成

 切换至备份文件目录查看备份的数据信息及创建生成的文件:

1

2

3

4

5

[root@stu18 ~]                 # cd /innobackup/2013-08-14_07-04-49/

[root@stu18 2013-08-14_07-04-49]                 # ls

backup-my.cnf  myclass             student            xtrabackup_binlog_info

hellodb        mysql                                test                                xtrabackup_checkpoints

ibdata1        performance_schema  xtrabackup_binary  xtrabackup_logfile

 针对文件解析:

   (1)xtrabackup_checkpoints —— 备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息;

      每个InnoDB页(通常为16k大小)都会包含一个日志序列号,即LSN。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的。

   (2)xtrabackup_binlog_info —— mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。

   (3)xtrabackup_binary —— 备份中用到的xtrabackup的可执行文件;

   (4)backup-my.cnf —— 备份时用到的配置选项信息,也就是配置文件中关于mysqld的相关文件配置;

   (5) xtrabackup_logfile —— 非文本文件是xtrabackup本身的日志文件;

4.4、准备一个完全备份

    一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处于不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件从而使得数据文件处于一致性状态。

   innobakupex命令的--apply-log选项可用于实现上述功能。如下面的命令:

1

2

3

4

5

6

[root@stu18 ~]                 # innobackupex -apply-log /innobackup/2013-08-14_07-04-49/

#############如果执行正确,其最后输出的几行信息通常如下################

xtrabackup: starting                  shutdown                  with innodb_fast_shutdown = 1

130814  7:39:33  InnoDB: Starting                  shutdown                 ...

130814  7:39:37  InnoDB: Shutdown completed; log sequence number 1606156

130814 07:39:37  innobackupex: completed OK!

4.5、模拟数据库崩溃实现完全恢复

 (1)模拟崩溃

1

2

3

[root@stu18 ~]                 # service mysqld stop

[root@stu18 ~]                 # cd /mydata/data/

[root@stu18 data]                 # rm -rf *

(2)从完全备份中恢复数据(谨记:在恢复数据之前千万不可初始化数据库和启动服务)

   innobackupex命令的--copy-back选项用于执行恢复操作,其通过复制所有数据相关的文件至mysql服务器DATADIR目录中来执行恢复过程。innobackupex通过backup-my.cnf来获取DATADIR目录的相关信息。

1

2

3

4

5

6

7

8

9

[root@stu18 ~]                 # innobackupex --copy-back /innobackup/2013-08-14_07-04-49/

#############如果执行正确,其最后输出的几行信息通常如下################

innobackupex: Starting to copy InnoDB log files

innobackupex:                  in                  '/innobackup/2013-08-14_07-04-49'

innobackupex: back to original InnoDB log directory                  '/mydata/data'

innobackupex: Copying                  '/innobackup/2013-08-14_07-04-49/ib_logfile0'                  to                 '/mydata/data'

innobackupex: Copying                  '/innobackup/2013-08-14_07-04-49/ib_logfile1'                  to                 '/mydata/data'

innobackupex: Finished copying back files.

130814 07:58:22  innobackupex: completed OK!

(3)当数据恢复至数据目录以后,还需要确保所有数据文件的属主和属组均为正确的用户,如mysql,否则,在启动mysqld之前还需要事先修改数据文件的属主和属组。

1

# chown -R mysql:mysql  /mydata/data/

(4)启动服务器登陆查看恢复完成。

1

[root@stu18 data]                 # service mysqld start

  注意:每一次恢复完成之后一定要重新做一次完全备份工作!!

4.6、使用innobackupex进行增量备份

   说明:每个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长。这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。

  • 第一次改动数据实现增量备份

  实现增量备份可以使用下面的命令进行:

1

[root@stu18 data]                 # innobackupex --user=root --password=mypass --incremental /innobackup --incremental-basedir=/innobackup/2013-08-14_08-14-12/

  其中,/innobackup指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/backup目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。--incremental-basedir是指向上一次完全备份所在的目录。

  • 第二次改动数据进行增量备份

1

[root@stu18 ~]                 # innobackupex --user=root --password=mypass --incremental /innobackup --incremental-basedir=/innobackup/2013-08-14_08-29-05/

   第二次增量备份的执行命令和第一次大致相同,只有其--incremental-basedir应该指向上一次的增量备份所在的目录。

  • 第三次改动数据还未进行增量备份

1

mysql> delete from coc where                  id                 =14;

4.7、使用innobackupex基于完全+增量+二进制日志恢复数据

 (1)由于笔者这里将二进制日志和数据文件写在了同一个文件目录下所以在模拟数据库崩溃前必须先复制出二进制日志文件,所以建议看客们将数据目录和二进制目录分开存放,不要和笔者一样犯如此二的错误。方法如下

    前提是在刚刚建立服务器尚未启动服务器之前做如下操作

1

2

3

4

mkdir                  /mybinlog                                 #建立一目录用于存放二进制日志

chown                  mysql:mysql                  /mybinlog                     #更改权限

vim                  /etc/my                 .cnf                                 #修改配置文件

log-bin=                 /mybinlog/mysql-bin                     #二进制日志目录及文件名前缀,添加之

  好了言归正传复制二进制日志文件

1

[root@stu18 data]                 # cp mysql-bin.000001/innobackup/

 (2)模拟服务器崩溃

1

2

3

[root@stu18 ~]                 # service mysqld stop

[root@stu18 ~]                 # cd /mydata/data/

[root@stu18 data]                 # rm -rf *

 (3)准备备份

      首先注意“准备”增量备份与整理完全备份有着一些不同,尤其要注意的是:

   1)需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行“重放”。“重放”之后,所有的备份数据将合并到完全备份上。

   2)基于所有的备份将未提交的事务进行“回滚”。

  • 完全备份“准备”

1

[root@stu18 ~]                 # innobackupex --apply-log --redo-only/innobackup/2013-08-14_08-14-12/

  • 第一次增量备份“准备”也就是说将第一次增量备份合并到了完全备份中

1

[root@stu18 ~]                 # innobackupex --apply-log--redo-only /innobackup/2013-08-14_08-14-12/--incremental-dir=/innobackup/2013-08-14_08-29-05/

  • 第二次增量备份“准备”也就是说将第二次增量备份也合并到了完全备份中

1

[root@stu18 ~]                 # innobackupex --apply-log--redo-only /innobackup/2013-08-14_08-14-12/ --incremental-dir=/innobackup/2013-08-14_09-08-39/

  其中 --redo-only是只将已提交的事务同步到数据文件中,未提交的事务日志不在进行回滚了

 (4)恢复数据(基于innobackupex基于完全+增量)

1

[root@stu18 ~]                 # innobackupex --copy-back/innobackup/2013-08-14_08-14-12/

 (5)更改属组属主

1

2

[root@stu18 ~]                 # cd /mydata/data/

[root@stu18 data]                 # chown -R mysql:mysql *

 (6)启动查看

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

[root@stu18 ~]                 # mysql -uroot -pmypas

mysql>                  select                  * from coc;

+----+---------+----------+

| ID | ClassID | CourseID |

+----+---------+----------+

|  1|       1 |        2 |

|  2|       1 |        5 |

|  3|       2 |        2 |

|  4|       2 |        6 |

|  5|       3 |        1 |

|  6|       3 |        7 |

|  7|       4 |        5 |

|  8|       4 |        2 |

|  9|       5 |        1 |

| 10 |      5 |        9 |

| 11 |      6 |        3 |

| 12 |      6 |        4 |

| 13 |      7 |        4 |

| 14 |      7 |        3 |

+----+---------+----------+

14 rows                  in                  set                  (0.00 sec)

   结果显示数据正确完整,但是第三次的改动信息未生效。

 (7)基于二进制日志实现数据恢复

   查看最后一次增量备份二进制日志所在的位置:

1

2

3

[root@stu18 data]                 # cd /innobackup/2013-08-14_09-08-39/

[root@stu18 2013-08-14_09-08-39]                 # cat xtrabackup_binlog_info

mysql-bin.000001    780

   查看二进制日志文件将未备份数据的二进制日志导出

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

[root@stu18 innobackup]                 # mysqlbinlog mysql-bin.000001

# at 780

#130814  9:20:19 server id 1  end_log_pos 851   Query   thread_id=7 exec_time=0  error_code=0

SET TIMESTAMP=1376443219/*!*/;

BEGIN

/*!*/;

# at 851

#130814  9:20:19 server id 1  end_log_pos 944   Query   thread_id=7 exec_time=0  error_code=0

SET TIMESTAMP=1376443219/*!*/;

delete from coc where                  id                 =14

/*!*/;

# at 944

#130814  9:20:19 server id 1  end_log_pos 1016  Query   thread_id=7 exec_time=0  error_code=0

SET TIMESTAMP=1376443219/*!*/;

COMMIT

/*!*/;

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

[root@stu18 innobackup]                 # mysqlbinlog --start-position=780 mysql-bin.000001 > ./all.sql     #导出数据

    恢复数据

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

[root@stu18 ~]                 # mysql -uroot –pmypass

mysql> SET SQL_LOG_BIN=0;                            #关闭二进制日志

mysql>                  source                  /innobackup/all                 .sql                    #导入数据

mysql> SET SQL_LOG_BIN=1;                            #开启二进制日志

mysql>                  select                  * from coc;                            #查看数据,恢复完成

+----+---------+----------+

| ID | ClassID | CourseID |

+----+---------+----------+

|  1 |       1 |        2 |

|  2 |       1 |        5 |

|  3 |       2 |        2 |

|  4 |       2 |        6 |

|  5 |       3 |        1 |

|  6 |       3 |        7 |

|  7 |       4 |        5 |

|  8 |       4 |        2 |

|  9 |       5 |        1 |

| 10 |       5 |        9 |

| 11 |       6 |        3 |

| 12 |       6 |        4 |

| 13 |       7 |        4 |

+----+---------+----------+

13 rows                  in                  set                  (0.00 sec)


   这种备份恢复方式完全以热备的形式实现完全备份和增量备份和二进制日志还原数据,并且恢复速度也很快,是最佳的备份恢复方式!!


   总结:以上三种备份恢复都是可以基于二进制日志文件进行的,因而体现出了二进制日志的重要性,从而映射出了日志的重要性;所以学习查看使用日志文件是学习Mysql的重中之重!





五、MYSQL的基本操作:增删查改

1、创建数据库: create database <数据库名>;
如:create database student;
2、连接到一个已经存在的数据库: use <数据库名>;
如:use student;
3、删除数据库:drop database <数据库名>;
如: drop database student;
4、创建表:create table <表名>(<列名><列的数据类型>[<列的约束>])
如:create table stuInfo(stuId int primary key,stuName varchar(20) not null)
5、删除表: drop table <表名>
如: drop table stuInfo;
6、修改表:alter table 
给表添加新列: alter table <表名> add <列名><列的数据类型>;
添加多列,中间用逗号隔开
如:alter table stuInfo add stuGender varchar(10)
修改某列的数据类型:alter table <表名> modify <列名><新数据类型>
如:alter table stuInfo modify stuGender int
修改列名:alter table <表名> change <老列名><新列名><数据类型>
如:alter table stuInfo change stuName stuAddress varchar(30)
删除列:alter table <表名> drop <列名>
如: alter table stuInfo drop stuGender
7、将创建的表的语句反向导出: show create table <表名>
8、查询表的所有内容:select * from <表名>
查询表的部分内容: select <列名列表> from <表名>
9、查询表结构:show columns from <表名>
10、插入单行数据:insert into <表名>(<列名列表>) values(<值列表>)
11、插入多行数据:作用相当于将数据从一个表复制到另一个表
insert into <表名> (列名列表) select <select语句>
如将stuInfo表中的所有的学生姓名复制到students表中的stuName列中:insert into students(stuName) select stuName from stuInfo
12、删除数据:delete from <表名> where<过滤条件>
如删除stuID为4的人的数据:delete from stuInfo where stuId=4



六、MYSQL的基本故障判断与处理

以下的文章主要介绍的是MySQL常见问题集锦,我们一共分成七大块对其进行说明,我们大家都知道MySQL数据库在是实际应用中的比例远少于Oracle,之所是这样的,肯定有它的不足之处  。

  MySQL常见问题集锦之一:

  MySQL(和PHP搭配之最佳组合)总是崩溃

  首先你应该试着找出问题MySQL(和PHP搭配之最佳组合)d守护进程是否死掉或你的问题是否与你的客户有关  。你可以用MySQL(和PHP搭配之最佳组合)admin version检查你的MySQL(和PHP搭配之最佳组合)d服务器正常执行了多长时间,如果MySQL(和PHP搭配之最佳组合)d死了,你可以在文件“MySQL(和PHP搭配之最佳组合)-data-directory/hostname.err”中找到其原因  。

  使用MySQL(和PHP搭配之最佳组合)时的一些常见错误

  


  1. MySQL(和PHP搭配之最佳组合) server has gone away 

  常见的原因是服务器超时了并且关闭了连接  。缺省地,如果没有事情发生,服务器在 8个小时后关闭连接  。你可在启动MySQL(和PHP搭配之最佳组合)d时通过设置wait_timeout变量改变时间限制  。

  如果MySQL(和PHP搭配之最佳组合)d得到一个太大或不正常的包,它认为客户出错了并关闭连接  。


  1. Cant connect to [local] MySQL(和PHP搭配之最佳组合) server 

  通常意味着没有一个MySQL(和PHP搭配之最佳组合)服务器运行在系统上或当试图连接MySQL(和PHP搭配之最佳组合)d服务器时,你正在使用一个错误的套接字文件或TCP/IP端口  。

  检查(使用ps)服务器上是否有一个名为MySQL(和PHP搭配之最佳组合)d的进程启动

  如果一个MySQL(和PHP搭配之最佳组合)d进程正在运行,可以通过尝试这些不同的连接来检查服务器

  shell> MySQL(和PHP搭配之最佳组合)admin version

  shell> MySQL(和PHP搭配之最佳组合)admin variables

  shell> MySQL(和PHP搭配之最佳组合)admin -h `hostname` version variables

  shell> MySQL(和PHP搭配之最佳组合)admin -h `hostname` --port=3306 version

  shell> MySQL(和PHP搭配之最佳组合)admin -h ip for your host version

  shell> MySQL(和PHP搭配之最佳组合)admin --socket=/tmp/MySQL(和PHP搭配之最佳组合).sock version

  注意hostname命令使用反引号“`”而非正引号“”;这些导致hostname输出(即,当前主机名)被代替进MySQL(和PHP搭配之最佳组合)admin命令中  。


  1. Host ... is blocked错误  

  2. Host hostname is blocked because of many connection errors.  

  3. Unblock with MySQL(和PHP搭配之最佳组合)admin flush-hosts  

  

  这意味着,MySQL(和PHP搭配之最佳组合)d已经得到了大量(max_connect_errors)的主机hostname的在中途被中断了的连接请求  。在max_connect_errors次失败请求后,MySQL(和PHP搭配之最佳组合)d认定出错了(象来字一个黑客的攻击),并且阻止该站点进一步的连接,直到某人执行命令MySQL(和PHP搭配之最佳组合)admin flush-hosts  。

  缺省地,MySQL(和PHP搭配之最佳组合)d在10个连接错误后阻塞一台主机  。你可以通过象这样启动服务器很容易地调整它:

  


  1. shell> safe_MySQL(和PHP搭配之最佳组合)d -O max_connect_errors=10000 & 

  MySQL常见问题集锦之二:Too many connections错误

  意味着已经有max_connections个客户连接了MySQL(和PHP搭配之最佳组合)d服务器  。

  如果你需要比缺省(100)更多的连接,那么你应该重启MySQL(和PHP搭配之最佳组合)d,用更大的 max_connections 变量值  。

  MySQL常见问题集锦之三:Out of memory错误

  MySQL(和PHP搭配之最佳组合): Out of memory at line 42, malloc.c

  MySQL(和PHP搭配之最佳组合): needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)

  ERROR 2008: MySQL(和PHP搭配之最佳组合) client ran out of memory

  注意,错误指向了MySQL(和PHP搭配之最佳组合)客户MySQL(和PHP搭配之最佳组合)  。这个错误的原因很简单,客户没有足够的内存存储全部结果  。

  首先检查你的查询是否正确

  MySQL常见问题集锦之四:Packet too large错误

  一个MySQL(和PHP搭配之最佳组合)客户或MySQL(和PHP搭配之最佳组合)d服务器得到一个比max_allowed_packet个字节长的包

  可以通过用MySQL(和PHP搭配之最佳组合) --set-variable=max_allowed_packet=8M指定一个更大的缓冲区来启动客户程序  。

  MySQL常见问题集锦之五:The table is full错误

  这个错误发生在内存临时表变得比tmp_table_size字节大时  。

  Commands out of sync in client错误

  正在以错误的次序调用客户函数!

  MySQL常见问题集锦之六:Ignoring user错误

  


  1. Found wrong password for user: some_user@some_host; Ignoring user 

  这意味着在MySQL(和PHP搭配之最佳组合)d启动时或在它再次装载权限表时,它在user表中找到了一个有一个无效口令的条目  。结果,条目简单地被权限系统忽略  。

  MySQL常见问题集锦之七:Table xxx doesnt exist错误

  数据库和表名件是区分大小写的!可以用SHOW TABLES检b查你在当前数据库中有哪个表  。

  

  从一个文本文件运行SQL命令

  可以把SQL命令放在一个文件中并且告诉MySQL(和PHP搭配之最佳组合)从该文件读取其输入:创造一个文本文件“text_file”,它包含要执行的命令  。然后如下调用MySQL(和PHP搭配之最佳组合):

  shell> MySQL(和PHP搭配之最佳组合) database < text_file

  或

  shell> MySQL(和PHP搭配之最佳组合) < text_file

  启动有USE db_name语句的文本文件  。

  

  怎样重新设置一个忘记的口令

  如果忘记了MySQL(和PHP搭配之最佳组合)的root用户的口令,可以使用如下方法恢复:

  通过发送一个kill(不是kill -9)到MySQL(和PHP搭配之最佳组合)d服务器来关闭MySQL(和PHP搭配之最佳组合)d服务器  。pid 被保存在一个.pid文件中,通常在MySQL(和PHP搭配之最佳组合)数据库目录中:

  kill `cat /MySQL(和PHP搭配之最佳组合)-data-directory/hostname.pid`

  你必须是一个UNIX root用户或运行服务器的相同用户做这个  。

  使用--skip-grant-tables选项重启MySQL(和PHP搭配之最佳组合)d  。

  用MySQL(和PHP搭配之最佳组合) -h hostname MySQL(和PHP搭配之最佳组合)连接MySQL(和PHP搭配之最佳组合)d服务器并且用一条GRANT命令改变口令  。见7.26 GRANT和REVOKE句法  。也可以用MySQL(和PHP搭配之最佳组合)admin -h hostname -u user password new password 进行  。

  用MySQL(和PHP搭配之最佳组合)admin -h hostname flush-privileges或用SQL命令FLUSH PRIVILEGES来装载权限表  。

  

  使用DATE列的问题

  DATE值的格式是YYYY-MM-DD  。

  

  改变一张表中列的顺序

  在一个应用程序中,应该决不基于他们的位置使用SELECT * 检索列,因为被返回的列的顺序永远不能保证;对数据库的一个简单改变可能导致应用程序相当有戏剧性地失败  。

  可以使用如下方法改变:

  以正确的列顺序创建一张新表  。

  


  1. 执行INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table.  

  删除或改名old_table  。

  


  1. ALTER TABLE new_table RENAME old_table  。  

  

  数据库复制

  MySQL(和PHP搭配之最佳组合)(至今)没有数据库复制,但是有一些如何实现的信息  。

  复制一个数据库最一般的方法是使用更新日志  。

  


七、MYSQL的调优


MySQL调优
 
调优思路:
1.数据库设计与规划--以后再修该很麻烦,估计数据量,使用什么存储引擎
2.数据的应用--怎样取数据,sql语句的优化
3.mysql服务优化--内存的使用,磁盘的使用
4.操作系统的优化--内核、tcp连接数量
5.升级硬件设备
 
 
磁盘io规划
raid技术:raid0[xfs]
swap分区:最好使用raid0
磁盘分区:一个库放到一个分区上或一个磁盘上
物理分区
create table t1(id int,name char(20)) data directory='/data/' index directory ='/data';
mkdir /data
chown mysql.mysql /data
 
mysql> show variables like '%part%';
 
 
4.操作系统的优化
网卡bonding技术,
tcp连接数量限制
优化系统打开文件的最大限制
关闭操作系统不必要的服务
 
5.mysql服务优化
show status  看系统的资源
show variables  看变量,在my.cnf配置文件里定义的
show warnings   查看最近一个sql语句产生的错误警告,看其他的需要看.err日志
show processlist显示系统中正在运行的所有进程。
show errors
 
启用mysql慢查询:---分析sql语句,找到影响效率的SQL
 
log-slow-queries=/var/lib/mysql/slow.log 这个路径对mysql用户具有可写权限
long_query_time=2   查询超过2秒钟的语句记录下来
上面的2 是查询的时间,即当一条SQL 执行时间超过5秒的时候才记录,/var/lib/mysql/slow.log 是日志记录的位置。
然后重新启动MySQL服务
 
对查询进行缓存
query_cache_size 使用多大内存来缓存查询语句[+8M]
mysql> show variables like'%query%'
query_cache_size=8M
[root@st mysql]# vim /etc/my.cnf
 
 
mysql> show status like '%Qcache%';
Qcache_free_blocks:说明缓存太大了。缓存中相邻内存的个数。数目大说明可能有碎片。FLUSH QUERY CACHE会对缓存中的碎片进行整理,从而得到一个空闲块。[+8M]
Qcache_free_memory缓存中的空闲内存
Qcache_hits每次查询在缓存中命中时就增大
Qcache_inserts每插入一个查询时就增大。命中次数除以插入次数就是命中率。
Qcache_lowmen_prunes缓存出现内存不足并且必须要进行清理以便为更多查询提供空间的次数。这个数字最好长时间看;如果这个数字在不断增长就表示可能碎片非常严重,或者内存很少
Qcache_hits/Qcache_inserts 命中率
 
关键字缓冲区
mysql> show status like '%key%';
mysql> show variables like'key_buffer_size';
 
key_buffer_size  指定索引缓冲区的大小,它决定索引处理的速度,尤其是索引读的速度。[+8M]
key_read_requests  请求总数
key_reads   代表命中磁盘的请求个数
(key_read_requests-key_read)/key_read_requests:命中率
key_buffer_size只对MyISAM表起作用。即使你不使用MyISAM表,但是内部的临时磁盘表是MyISAM表,也要使用该值。可以使用检查状态值created_tmp_disk_tables得知详情。
对于1G内存的机器,如果不使用MyISAM表,推荐值是16M(8-64M)。
 
临时表空间大小:order by和group by时把数据放到临时表里。
tmp_table_size   占的是内存的大小,如果太小在排序时会出错
created_tmp_tables  创建临时表的数量
max_tmp_tables=32
tmpdir=/tmp  硬盘上临时表所在的位置
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
innodb表:
创建表空间文件
[mysqld]
innodb_data_file_path=ibdata1:10M:autoextend
这个设置配置一个可扩展大小的尺寸为10MB的单独文件,名为ibdata1。没有给出文件的位置,所以默认的是在MySQL的数据目录内。
如果你对最后的数据文件指定autoextend选项。如果数据文件耗尽了表空间中的自由空间,InnoDB就扩展数据文件。扩展的幅度是每次8MB。
要为一个自动扩展数据文件指定最大尺寸,请使用max属性。下列配置允许ibdata1涨到极限的500MB:
[mysqld]
innodb_data_file_path=ibdata1:10M:autoextend:max:500M
InnoDB默认地在MySQL数据目录创建表空间文件。要明确指定一个位置,请使用innodb_data_home_dir选项。比如,要使用两个名为ibdata1和ibdata2的文件,但是要把他们创建到/ibdata,像如下一样配置InnoDB:
[mysqld]
innodb_data_home_dir = /ibdata
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
 
mysql> show variables like 'innodb_buffer_pool_size';
innodb_buffer_pool_size
对于InnoDB表来说,innodb_buffer_pool_size的作用就相当于key_buffer_size对于MyISAM表的作用一样。InnoDB使用该参数指定大小的内存来缓冲数据和索引。对于单独的MySQL数据库服务器,最大可以把该值设置成物理内存的80%。
根据MySQL手册,对于2G内存的机器,推荐值是1G(50%)。
 
mysql> show variables like 'innodb_%per%';[建议打开]
innodb_file_per_table =1 为每一个表单独创建一个表空间文件。
其他参数
skip-locking
取消文件系统的外部锁,减少出错几率增强稳定性
 
skip-name-resolve
关闭mysql的dns反查功能。这样速度就快了!
选项就能禁用DNS解析,连接速度会快很多。不过,这样的话就不能在MySQL的授权表中使用主机名了而只能用ip格式。
 
wait_timeout=10 终止空闲时间超过10秒的链接,避免长连接[默认8个小时]
 
max_connect_errors=10 //10次连接失败就锁定,使用flush hosts 解锁,
或mysqladmin flush-hosts解锁
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL语句调优:
explain命令:查询select。
.type
这列很重要,显示了连接使用了哪种类别,有无使用索引
从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL
 
-----------------------------

MySQL性能诊断与调优


LAMP 系统性能调优,第 3 部分: MySQL 服务器调优
http://www.ibm.com/developerworks/cn/linux/l-tune-lamp-3.html

LoadRunner监控MySQL
http://www.docin.com/p-92272846.html

Advanced MySQL Performance Optimization
http://www.mysqlperformanceblog.com/files/presentations/UC2005-Advanced-MySQL-

Performance-Optimization.pdf

Improving MySQL Server Performance with Intel C++ Compiler
http://www.mysqlperformanceblog.com/files/presentations/LinuxWorld2005-Intel.pdf


MySQL性能诊断与调优相关工具:
http://www.mysqlperformanceblog.com/tools/
http://hackmysql.com/mysqlreport

Spotlight On MySQL:
http://www.quest.com/spotlight-on-mysql/

Mysql Administator

http://downloads.mysql.com/archives.php?p=MySQLAdministrationSuite

phpMyAdmin

http://www.phpmyadmin.net/home_page/index.php

 


mysql slow log分析工具
http://hackmysql.com/
http://www.willamowius.de/mysql-tools.html
http://code.google.com/p/mysql-log-filter/
http://myprofi.sourceforge.net/

 

mysql网络协议嗅探工具 - mysqlsniffer

http://hackmysql.com/mysqlsniffer 

 

MySQL性能诊断与调优相关书籍:
《High Performance MySQL Second Edition》

 

优化mysql数据库性能的十个参数
(1)、max_connections:
允许的同时客户的数量。增加该值增加 mysqld 要求的文件描述符的数量。这个数字应该增加,否则,你将经常看到 too many connections 错误。 默认数值是100,我把它改为1024 。
(2)、record_buffer:
每个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。如果你做很多顺序扫描,你可能想要增加该值。默认数值是131072(128k),我把它改为16773120 (16m)
(3)、key_buffer_size:
索引块是缓冲的并且被所有的线程共享。key_buffer_size是用于索引块的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写),到你能负担得起那样多。如果你使它太大,系统将开始换页并且真的变慢了。默认数值是8388600(8m),我的mysql主机有2gb内存,所以我把它改为 402649088(400mb)。
4)、back_log:
要求 mysql 能有的连接数量。当主要mysql线程在一个很短时间内得到非常多的连接请求,这就起作用,然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。
back_log 值指出在mysql暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接,你需要增加它,换句话说,这值对到来的tcp/ip连接的侦听队列的大小。你的操作系统在这个队列大小上有它自己的限制。试图设定back_log高于你的操作系统的限制将是无效的。
当你观察你的主机进程列表,发现大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | null | connect | null | login | null 的待连接进程时,就要加大 back_log 的值了。默认数值是50,我把它改为500。
(5)、interactive_timeout:
服务器在关闭它前在一个交互连接上等待行动的秒数。一个交互的客户被定义为对 mysql_real_connect()使用 client_interactive 选项的客户。 默认数值是28800,我把它改为7200。
(6)、sort_buffer:
每个需要进行排序的线程分配该大小的一个缓冲区。增加这值加速order by或group by操作。默认数值是2097144(2m),我把它改为 16777208 (16m)。
(7)、table_cache:
为所有线程打开表的数量。增加该值能增加mysqld要求的文件描述符的数量。mysql对每个唯一打开的表需要2个文件描述符。默认数值是64,我把它改为512。
(8)、thread_cache_size:
可以复用的保存在中的线程的数量。如果有,新的线程从缓存中取得,当断开连接的时候如果有空间,客户的线置在缓存中。如果有很多新的线程,为了提高性能可以这个变量值。通过比较 connections 和 threads_created 状态的变量,可以看到这个变量的作用。我把它设置为 80。
(9)mysql的搜索功能
用mysql进行搜索,目的是能不分大小写,又能用中文进行搜索
只需起动mysqld时指定 --default-character-set=gb2312
(10)、wait_timeout:
服务器在关闭它之前在一个连接上等待行动的秒数。 默认数值是28800,我把它改为7200。
注:参数的调整可以通过修改 /etc/my.cnf 文件并重启 mysql 实现。这是一个比较谨慎的工作,上面的结果也仅仅是我的一些看法,你可以根据你自己主机的硬件情况(特别是内存大小)进一步修改。



八、MYSQL主主、主从复制的实现


见SVN文档


九、MYSQL大数据备份和恢复


见SVN文档


十、数据文件的损坏与修复

1.       表损坏的原因分析
以下原因是导致mysql 表毁坏的常见原因:
1、 服务器突然断电导致数据文件损坏。
2、 强制关机,没有先关闭mysql 服务。
3、 mysqld 进程在写表时被杀掉。
4、 使用myisamchk 的同时,mysqld 也在操作表。
5、 磁盘故障。
6、 服务器死机。
7、 mysql 本身的bug 。

2.       表损坏的症状
一个损坏的表的典型症状如下:
1 、当在从表中选择数据之时,你得到如下错误:
Incorrect key file for table: '...'. Try to repair it
2 、查询不能在表中找到行或返回不完全的数据。
3 、Error: Table 'p' is marked as crashed and should be repaired 。
4 、打开表失败: Can’t open file: ‘×××.MYI’ (errno: 145) 。
5 、

3.       预防 MySQL表损坏
可以采用以下手段预防mysql 表损坏:
1 、定期使用myisamchk 检查MyISAM 表(注意要关闭mysqld ),推荐使用check table 来检查表(不用关闭mysqld )。
2 、在做过大量的更新或删除操作后,推荐使用OPTIMIZE TABLE 来优化表,这样既减少了文件碎片,又减少了表损坏的概率。
3 、关闭服务器前,先关闭mysqld (正常关闭服务,不要使用kill -9 来杀进程)。
4 、使用ups 电源,避免出现突然断电的情况。
5 、使用最新的稳定发布版mysql ,减少mysql 本身的bug 导致表损坏。
6 、对于InnoDB 引擎,你可以使用innodb_tablespace_monitor 来检查表空间文件内文件空间管理的完整性。
7 、对磁盘做raid ,减少磁盘出错并提高性能。
8 、数据库服务器最好只跑mysqld 和必要的其他服务,不要跑其他业务服务,这样减少死机导致表损坏的可能。
9 、不怕万一,只怕意外,平时做好备份是预防表损坏的有效手段。

4.       MySQL表损坏的修复
MyISAM 表可以采用以下步骤进行修复 :
1、  使用 reapair table 或myisamchk 来修复。
2、  如果上面的方法修复无效,采用备份恢复表。

具体可以参考如下做法:
阶段1 :检查你的表
如果你有很多时间,运行myisamchk *.MYI 或myisamchk -e *.MYI 。使用-s (沉默)选项禁止不必要的信息。
如果mysqld 服务器处于宕机状态,应使用--update-state 选项来告诉myisamchk 将表标记为' 检查过的' 。
你必须只修复那些myisamchk 报告有错误的表。对这样的表,继续到阶段2 。
如果在检查时,你得到奇怪的错误( 例如out of memory 错误) ,或如果myisamchk 崩溃,到阶段3 。
阶段2 :简单安全的修复
注释:如果想更快地进行修复,当运行myisamchk 时,你应将sort_buffer_size 和Key_buffer_size 变量的值设置为可用内存的大约25% 。
首先,试试myisamchk -r -q tbl_name(-r -q 意味着“ 快速恢复模式”) 。这将试图不接触数据文件来修复索引文件。如果数据文件包含它应有的一切内容和指向数据文件内正确地点的删除连接,这应该管用并且表可被修复。开始修复下一张表。否则,执行下列过程:
在继续前对数据文件进行备份。
使用myisamchk -r tbl_name(-r 意味着“ 恢复模式”) 。这将从数据文件中删除不正确的记录和已被删除的记录并重建索引文件。
如果前面的步骤失败,使用myisamchk --safe-recover tbl_name 。安全恢复模式使用一个老的恢复方法,处理常规恢复模式不行的少数情况( 但是更慢) 。
如果在修复时,你得到奇怪的错误( 例如out of memory 错误) ,或如果myisamchk 崩溃,到阶段3 。
阶段3 :困难的修复
只有在索引文件的第一个16K 块被破坏,或包含不正确的信息,或如果索引文件丢失,你才应该到这个阶段。在这种情况下,需要创建一个新的索引文件。按如下步骤操做:
把数据文件移到安全的地方。
使用表描述文件创建新的( 空) 数据文件和索引文件:
shell> mysql db_name
mysql> SET AUTOCOMMIT=1;
mysql> TRUNCATE TABLE tbl_name;
mysql> quit
如果你的MySQL 版本没有TRUNCATE TABLE ,则使用DELETE FROM tbl_name 。
将老的数据文件拷贝到新创建的数据文件之中。(不要只是将老文件移回新文件之中;你要保留一个副本以防某些东西出错。)
回到阶段2 。现在myisamchk -r -q 应该工作了。(这不应该是一个无限循环)。
你还可以使用REPAIR TABLE tbl_name USE_FRM ,将自动执行整个程序。
阶段4 :非常困难的修复
只有.frm 描述文件也破坏了,你才应该到达这个阶段。这应该从未发生过,因为在表被创建以后,描述文件就不再改变了。
从一个备份恢复描述文件然后回到阶段3 。你也可以恢复索引文件然后回到阶段2 。对后者,你应该用myisamchk -r 启动。
如果你没有进行备份但是确切地知道表是怎样创建的,在另一个数据库中创建表的一个拷贝。删除新的数据文件,然后从其他数据库将描述文件和索引文件移到破坏的数据库中。这样提供了新的描述和索引文件,但是让.MYD 数据文件独自留下来了。回到阶段2 并且尝试重建索引文件。


InnoDB 表可以采用下面的方法修复:
如果数据库页被破坏,你可能想要用SELECT INTO OUTFILE 从从数据库转储你的表,通常以这种方法获取的大多数数据是完好的。即使这样,损坏可能导致SELECT * FROM tbl_name 或者InnoDB 后台操作崩溃或断言,或者甚至使得InnoDB 前滚恢复崩溃。 尽管如此,你可以用它来强制InnoDB 存储引擎启动同时阻止后台操作运行,以便你能转储你的表。例如:你可以在重启服务器之前,在选项文件的[mysqld] 节添加如下的行:
    [mysqld]innodb_force_recovery = 4innodb_force_recovery 被允许的非零值如下。一个更大的数字包含所有更小数字的预防措施。如果你能够用一个多数是4 的选项值来转储你的表,那么你是比较安全的,只有一些在损坏的单独页面上的数据会丢失。一个为6 的值更夸张,因为数据库页被留在一个陈旧的状态,这个状态反过来可以引发对B 树和其它数据库结构的更多破坏。
    1 (SRV_FORCE_IGNORE_CORRUPT)
即使服务器检测到一个损坏的页,也让服务器运行着;试着让SELECT * FROM tbl_name 跳过损坏的索引记录和页,这样有助于转储表。
    2 (SRV_FORCE_NO_BACKGROUND)
阻止主线程运行,如果崩溃可能在净化操作过程中发生,这将阻止它。
    3 (SRV_FORCE_NO_TRX_UNDO)
恢复后不运行事务回滚。
    4 (SRV_FORCE_NO_IBUF_MERGE)
也阻止插入缓冲合并操作。如果你可能会导致一个崩溃。最好不要做这些操作,不要计算表统计表。
    5 (SRV_FORCE_NO_UNDO_LOG_SCAN)
启动数据库之时不查看未完成日志:InnoDB 把未完成的事务视为已提交的。
    6 (SRV_FORCE_NO_LOG_REDO)
不要在恢复连接中做日志前滚。
    数据库不能另外地带着这些选项中被允许的选项来使用。作为一个安全措施,当innodb_force_recovery 被设置为大于0 的值时,InnoDB 阻止用户执行INSERT, UPDATE 或DELETE 操作.
    即使强制恢复被使用,你也可以DROP 或CREATE 表。如果你知道一个给定的表正在导致回滚崩溃,你可以移除它。你也可以用这个来停止由失败的大宗导入或失败的ALTER TABLE 导致的失控回滚。你可以杀掉mysqld 进程,然后设置innodb_force_recovery 为3 ,使得数据库被挂起而不需要回滚,然后舍弃导致失控回滚的表。


你可能感兴趣的:(MYSQL数据库常用知识整理)