MySQL 事务
事务:事务是并发控制的基本单元,事务是对数据库进行读或写的一个操作序列,要么都执行,要么都不执行,他是一个不可分割的工作单位,事务是维护数据库一致性的单位。
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,
你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库
操作语句就构成一个事务!
在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
事务用来管理 insert,update,delete 语句
事务存在的目的:
1.为数据库操作提供了一个从失败中恢复到正常的方法,保持数据库的一致性
2.在多个应用程序并发访问数据库时,为其提供一个隔离的方法,为防止彼此的操作相互干扰
事务必须满足的4个条件(ACID):
ACID:原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性:事务处理结束后,对数据库的修改就是永久的,即便系统故障也不会丢失。
事务的隔离机制:
有四种隔离机制:
1、Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大;
2、REPEATABLE READ(重复读) :保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但不能避免“幻读”,但是带来了更多的性能损失。
3、READ COMMITTED (提交读):大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适用于大多数系统。
4、Read Uncommitted(未提交读) :事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”。
脏读:所谓的脏读,其实就是读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。也就是说,当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据。
不可重复读:事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。
也就是说,当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应了不可重复读的语义。
幻读:事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。
也就是说,当前事务读第一次取到的数据比后来读取到数据条目少。
事物的语句:
开始事务:BEGIN TRANSACTION
提交事务:COMMIT TRANSACTION
回滚事务:ROLLBACK TRANSACTION
什么是索引?
索引在mysql中也叫键,是存储引擎用于快速查找记录的一种数据结构。通过不断地缩小想要的数据的
范围来筛选最终想要的结构,同时把随机的事件变为顺序的事件。索引的作用相当于图书的目录,可以根据
目录中的页码快速找到所需的内容。在表中建立索引,然后在索引中找到符合查询条件的索引值,
最后通过保存在索引中的ROWID(相当于页码)快速找到表中对应的记录。这样就不会消耗大量数据库
系统时间,并造成大量磁盘I/O操作
优点
1.大大加快数据的检索速度;
2.创建唯一性索引,保证数据库表中每一行数据的唯一性;
3.加速表和表之间的连接;
4.在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。
缺点
1.索引需要占物理空间。
2.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。
alter table `table_name` add index index_name(`colum`)
主键、外键、唯一索引的区别:
主键:主键是能确定一条记录的唯一标识,比如,一条记录包括身份正号,姓名,年龄。
身份证号是唯一能确定你这个人的,其他都可能有重复,所以,身份证号是主键。
外键:外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。
比如,A表中的一个字段,是B表的主键,那他就可以是A表的外键。
唯一索引:一种索引,不允许具有索引值相同的行,从而禁止重复的索引或键值。唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。
创建主键:ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
创建唯一索引:ALTER TABLE `table_name` ADD UNIQUE ( `column` )
创建外键:alter table student add foreign key foreign_cid (CID) references courses (CID);
1.主键一定是唯一性索引,唯一性索引并不一定就是主键。
2.一个表中可以有多个唯一性索引,但只能有一个主键。
3.主键列不允许空值,而唯一性索引列允许空值。
4.索引可以提高查询的速度。
create tables tb1(id int not null auto_increament,name varchar(20) not null, age varchar(20) not null,PRIMORY(id),index(age));
create table tb2 select * from tb1 where id <=2;
create table tb3 like tb1;
聚集索引和非聚集索引的区别?
索引是对数据库表中一个或多个列(例如,employee 表的姓名 (name) 列)的值进行排序的结构。
例如这样一个查询:select * from table1 where id=10000。如果没有索引,必须遍历整个表,
直到ID等于10000的这一行被找到为止;有了索引之后(必须是在ID这一列上建立的索引),即可在索
引中查找。由于索引是经过某种算法优化过的,因而查找次数要少的多。可见,索引是用来定位的。
聚集索引:
在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。
如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集
索引通常提供更快的数据访问速度。聚集索引和非聚集索引的区别,如字典默认按字母顺序排序,读者
如知道某个字的读音可根据字母顺序快速定位。因此聚集索引和表的内容是在一起的。如读者需查询
某个生僻字,则需按字典前面的索引,举例按偏旁进行定位,找到该字对应的页数,再打开对应页数
找到该字。这种通过两个地方而查询到某个字的方式就如非聚集索引
主从复制原理
1.从库的io线程向主库的主进程发送连接请求,主库验证从库,交给主库的io线程负责数据的传输
2.主库的io线程对比从库发过来的master.infO里的信息,将binlog文件信息,偏移量和binlog文件名
等发送给从数据库
3.从库接收到信息后,将binlog信息保存在realylog中,同时更新master.info的偏移量和binlog文件名
4.从库的sql线程不断的读取realy-bin中的信息,并且根据relay log 的内容对slave数据库做相应的操作。
5.完成上次同步后,从库的io线程不断地向主库的io线程要binlog数据
Salve的IO线程会读取mastr.info文件中配置好的主库信息,比如说存放的有:Master数据库的用户名、
密码、端口、还有Master的binlog索引位置;
拿到信息之后就带着信息去链接Master的主库IO线程
当主库的IO线程先检查SLave传过来的配置信息是否正确,如果正确,就拿着Slave传过来的binlog索引位置和Master库的binlog文件中最后一个索引位置进行对比,如果一致就陷入等待状态,等待Master的binlog索引位置更新;
如果不一致就把Slave传过来的binlog索引位置往后的所有SQL语句包括最后一条SQL语句的索引位置发送个给Slave的IO线程;
Slave的IO线程拿到信息之后,先把Master传过来的binlog索引在Slave的master.info文件中进行更新;
然后再把Master传过来的SQL语句写入到relay文件中,然后继续循环执行第二个步骤;
Slave的SQL线程会一直持续的观察relay日志文件中是否有改动,如果没有就继续监听;
如果发现relay中有变动,那么就获取变动的内容转换为SQL语句,并且把SQL语句在Salve的数据库中进行执行
mysql的常用引擎
Innodb引擎,Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。
它的设计的目标就是处理大数据容量的数据库系统。它本身实际上是基于Mysql后台的完整的系统。
Mysql运行的时候,Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是,该引擎是不支持
全文搜索的。同时,启动也比较的慢,它是不会保存表的行数的。当进行Select count(*) from
table指令的时候,需要进行扫描全表。所以当需要使用数据库的事务时,该引擎就是首选。由于锁
的粒度小,写操作是不会锁定全表的。所以在并发度较高的场景下使用会提升效率的。
MyIASM引擎,它是MySql的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行Insert
插入和Update更新语句时,即执行写操作的时候需要锁定这个表。所以会导致效率会降低。不过和Innodb
不同的是,MyIASM引擎是保存了表的行数,于是当进行Select count(*) from table语句时,可以直接
的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务
的支持的。可以将MyIASM作为数据库引擎的首先
总结: MYIASM管理非事务表,提供高速存储和检索,以及全文搜索能力,如果在应用中执行大量的select操作,应选择MYIASM引擎
Innodb用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量的insert和update操作,应选择innodb引擎。
Mysql的日志文件类型:
错误日志:
1) 记录服务器启动关闭过程的信息;
2) 记录服务器运行过程中的错误信息;
3) 记录事件调试器运行一个事件时产生的信息;
4) 记录在从服务器上启动从服务器进程时产生的信息。
日志位置查看与修改:
查看:SHOW GLOBAL VARIABLES LIKE '%log_error%'
修改:/etc/init.d/mysql start --log_error=/tmp/mySql.errorLog.err。这种修改只会对本次启动有效,如果关闭并重启MySQL则log_error的值将又变为默认值,如果需要永久修改,那么就必须在my.cnf中指定log_error参数的值。
普通查询日志:
查询日志会记录用户的所有操作,其中包括用户的增删改查等信息,该日志默认情况下是未启用的。因为在并发操作下会产生大量的日志信息而导致不必要的磁盘IO和空间占用。不是为了调试数据库的目的建议不要开启查询日志。
日志位置查看:
SHOW GLOBAL VARIABLES LIKE '%general_log%';
慢查询日志:
慢查询日志是记录那些超过long_query_time参数设定时间和未使用索引的的查询语句,通过将log_queries_not_using_indexes参数设置为true;可以将所有没有使用到索引的sql语句都记录到慢查询日志中。慢查询日志默认情况为关闭状态,建议开启。
事务日志:
事务日志是InnoDB存储引擎特有的日志,主要分为重做日志(redo)和回滚日志(undo)。事务日志文件名为"ib_logfile0"和“ib_logfile1”,默认存放在表空间所在目录。存储引擎在修改表数据时只需修改其内存拷贝,再把修改行为记录到持久硬盘上的事务日志中,而不必将修改的数据持久到磁盘。事务日志写操作是磁盘某区域内的顺序IO,不需要多次寻址,因此效率相对较高。事务日志持久化后,内存中被修改的数据在后台可以慢慢的刷回磁盘,因此修改数据需要写两次磁盘。MySQL在崩溃后,重启服务,InnoDB通过回滚日志undo将所有已完成并写入磁盘的未完成事务进行rollback,然后redo中的事务全部重新执行一遍即可恢复数据,但是随redo的量增加,每次从redo的第一条开始恢复就会浪费长的时间,所以引入了checkpoint机制。
二进制日志:
MySQL中的二进制日志(binary log)是一个二进制文件,主要用于记录可能引起数据库内容更改的SQL语句或数据行记录,例如新增(Insert)、更新(Update)、删除(Delete)、授权信息变更(Grant Change)等,除记录这些外,还会记录变更语句的发生时间、执行时长、操作数据等额外信息,但是它不会记录诸如Select、Show等这些不会引起数据修改的SQL语句。
中继日志:
中继日志是在MySQL进行主从复制时使用一种日志, 是从主服务器的二进制日志文件中复制到从服务器,并保存为的日志文件。
1)log_slave_updates
用于设定复制场景中的从服务器是否将从主服务器收到的更新操作记录进本机的二进制日志中。本参数设定的生效需要在从服务器上启用二进制日志功能。
2)relay_log=file_name
设定中继日志的文件名称,默认为host_name-relay-bin。也可以使用绝对路径,以指定非数据目录来存储中继日志。作用范围为全局级别,可用于选项文件属非动态变量。
显示二进制日志相关语句:
mysql> SHOW {BINARY | MASTER} LOGS ; #显示当前mysql有哪些二进制日志文件
mysql> SHOW MASTER STATUS; #显示当前服务器所使用的二进制日志文件及所处的位置
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000021 | 311 | | |
+------------------+----------+--------------+------------------+
mysql> SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]; #读取二进制日志的事件详情
mysql> SHOW BINLOG EVENTS IN 'mysql-bin.000021';
+------------------+-----+-------------+-----------+-------------+---------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------------------------+
| mysql-bin.000021 | 4 | Format_desc | 1 | 107 | Server ver: 5.5.36-log, Binlog ver: 4 |
| mysql-bin.000021 | 107 | Query | 1 | 213 | use `mydb2`; DROP TABLE `tb2` /* generated by server */ |
| mysql-bin.000021 | 213 | Query | 1 | 311 | use `mydb2`; CREATE TABLE tb2 SELECT * FROM tb1 |
+------------------+-----+-------------+-----------+-------------+---------------------------------------------------------
mysql> SHOW BINLOG EVENTS IN 'mysql-bin.000021' FROM 213; #指定位置
+------------------+-----+------------+-----------+-------------+-------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+------------+-----------+-------------+-------------------------------------------------+
| mysql-bin.000021 | 213 | Query | 1 | 311 | use `mydb2`; CREATE TABLE tb2 SELECT * FROM tb1 |
+------------------+-----+------------+-----------+-------------+-------------------------------------------------+
在shell下也有相关的工具读取二进制日志文件,比在交互式环境读取的信息更可读:
[root@mariadb ~]# mysqlbinlog /mydata/data/mysql-bin.000021
借助二进制日志文件和mysqlbinlog命令可实现数据的恢复操作,此命令常用的4个选项:
--start-datetime=#
表示二进制日志文件中一个事件的开始时间
--stop-datetime=#
表示二进制日志文件中一个事件的结束时间
--start-position=#
表示二进制日志文件中一个事件的开始位置
--stop-position=#
表示二进制日志文件中一个事件的结束位置
二进制日志文件安全的的删除方法(删除前请备份):
语法: PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
mysql> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 27702 |
| mysql-bin.000002 | 1063490 |
| mysql-bin.000003 | 733 |
| mysql-bin.000004 | 150 |
| mysql-bin.000007 | 126 |
| mysql-bin.000008 | 126 |
| mysql-bin.000009 | 126 |
| mysql-bin.000010 | 126 |
| mysql-bin.000011 | 381 |
| mysql-bin.000012 | 126 |
| mysql-bin.000013 | 1625 |
mysql> PURGE BINARY LOGS TO 'mysql-bin.000010'; #把此二进制日志文件之前的都删除
Query OK, 0 rows affected (0.04 sec)
mysql> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000010 | 126 |
| mysql-bin.000011 | 381 |
| mysql-bin.000012 | 126 |
| mysql-bin.000013 | 1625 |
mysql的备份
冷备份
冷备份发生在数据库已经正常关闭的情况下,当正常关闭时会提供给我们一个完整的数据库。冷备份是将关键性文件拷贝到另外位置的一种说法。对于备份数据库信息而言,冷备份是最快和最安全的方法。
冷备份的优点:
1.是非常快速的备份方法(只需拷贝文件)
2.容易归档(简单拷贝即可)
3.容易恢复到某个时间点上(只需将文件再拷贝回去)
4.能与归档方法相结合,作数据库“最新状态”的恢复。
5.低度维护,高度安全。
冷备份的缺点:
1.单独使用时,只能提供到“某一时间点上”的恢复。
2.在实施备份的全过程中,数据库必须要作备份而不能作其它工作。也就是说,在冷备份过程中,数据库必须是关闭状态。
3.若磁盘空间有限,只能拷贝到磁带等其它外部存储设备上,速度会很慢。
4.不能按表或按用户恢复。
值得注意的是冷备份必须在数据库关闭的情况下进行,当数据库处于打开状态时,执行数据库文件系统备份是无效的 。而且在恢复后一定要把数据库文件的属组和属主改为mysql。
热备份
热备份是在数据库运行的情况下,备份数据库操作的sql语句,当数据库发生问题时,可以重新执行一遍备份的sql语句。
热备份的优点:
1.可在表空间或数据文件级备份,备份时间短。
2.备份时数据库仍可使用。
3.可达到秒级恢复(恢复到某一时间点上)。
4.可对几乎所有数据库实体作恢复。
5.恢复是快速的,在大多数情况下在数据库仍工作时恢复。
热备份的缺点:
1.不能出错,否则后果严重。
2.若热备份不成功,所得结果不可用于时间点的恢复。
3.因难于维护,所以要特别仔细小心,不允许“以失败而告终”。
mysql的备份和恢复
Mysql备份常用方法(逻辑备份和物理备份)
物理备份:直接拷贝库或者表对应的文件。使用cp,rsync,tar,scp等工具。具有局限性,前提是表的存储引擎为myisam,跨平台性差,数据备份恢复浪费时间。并且由于在备份期间数据依然在写数据,所以直接复制会引起数据丢失,在恢复数据库时,对新数据库的路径,配置也有要求,一般要和远程保持一致。为了确保数据一致性,可以选择人工停库或者锁库后进行。但是一般生产不允许,除非可以申请停机或锁表
物理备份备份方法
物理备份两部:1、停库或锁表,打包拷贝 2、第三方xtrabackup
逻辑备份:执行备份时,根据已有的数据,生成对应的sql命令,把sql保存到指定的文件里。恢复时执行备份文件里的sql命令,将备份的sql语句还原到mysql数据库中。
补充:增量备份备份binlog日志文件即可,恢复增量即通过mysqlbinlog工具截取binlog日志转换成sql语句,通过mysql或source进行语句还原
数据备份策略
完全备份:备份所有数据。
增量备份:备份自上一次备份之后有变化的数据
差异备份:备份自完全备份之后有变化的数据
完全备份+增量备份
完全备份+差异备份
MySql的备份命令
完全备份:
mysqldump -hlocalhost -uroot -p密码 源库名 >文件名
源库名的表示:
--all-databases,-A 所有库
库名 指定单个库
库名 表名 指定库的表(注意库名和表名之间是空格)
-B 数据库1 数据库2 备份多个库
恢复命令:
两种方式:
(1)mysql 连接库操作 目标库名 <文件名.sql
(2)mysql>source 备份文件路径;
增量备份
(1)启用binlog日志 实现实时增量备份
binlog日志介绍:二进制日志,是mysql数据库服务日志文件中的一种,记录执行的除查询之外的sql命令。默认没有启用。
vim /etc/my.cnf
[mysqld]
server_id=数值 #数值范围1-255
log_bin #启用默认存放路径/var/lib/mysql/
binlog_format="mixed"
重启服务之后生成的文件为:
/var/lib/mysql/主机名-bin.000001
#超过500M生成新的(000001-999999)
/var/lib/mysql/localhost-bin.index #索引文件
#systemctl restart mysqld #重启服务
(2)查看日志当前记录格式
mysql > show variables like "binlog_format";
三种记录格式:
statement:每一条修改数据的sql命令都会记录在binlog日志中;
row:不记录sql语句上下文相关信息,仅保存哪条记录被修改;
mixed:是以上两种格式的混合使用。
(3)查看binlog日志文件内容
mysqlbinlog /var/lib/mysql/localhost-bin.000001
mysqlbinlog localhost-bin.000001 | grep -i insert
(4)分析binlog日志
binlog日志文件记录sql命令的方式:
时间点
--start-datetime="yyyy-mm-dd hh:mm:ss"
--stop-datetime="yyyy-mm-dd hh:mm:ss"
pos点(偏移量)
--start-position=数字
--stop-position=数字
-r 相当于重定向
(5)执行binlog日志里的sql命令恢复数据
mysqlbinlog [选项] 日志文件名 | mysql -uroot -p123qqq
mysqlbinlog --start-position=300 --stop-position=1006 /var/lib/mysql/localhost-bin.000001 | mysql -uroot -p123456
(6)手动生成新的binlog日志
第1种:mysql> flush logs; #刷新一次生成一次
第2种:mysql -uroot -p123qqq -e "flush logs" #-e就是以mysql登录方式执行sql命令
第3种: systemctl restart mysqld
第4种: mysqldump -uroot -p123qqq --flush-logs teadb t7 > /databak/t7.sql #备份的时候重新生成
(7)删除已有的binlog日志文件
第1种:mysql> reset master; #重置所有
第2种:mysql> purge master logs to "binlog文件名"; #删除指定binlog之前的日志
第3种:rm -rf binlog日志文件
第4种:grep expire /data/3306/my.cnf #配置文件自动删
expire_logs_days = 7 #自动删除7天前的备份
完全备份+增量备份
mysqldump用于对某一时刻的数据全备,例如在0点进行备份bak.sql.gz
增量备份:当有数据写入到数据库时,还会同时把更新的sql语句写入到对应文件里,即binlog文件
10点丢失数据需要恢复,处理方法如下:
a、将0点时刻的备份bak.sql.gz数据还原,即数据库数据截至时间为00点
b、0点到10点的数据,从binlog里恢复
# mysqldump -uroot -p --master-data=2 --flush-logs --all-databases --lock-all-tables > /root/alldatabase.sql
--lock-all-table:锁定所有表
--flush-logs:刷新日志,生成新的日志文件
--master-data={0|1|2}
0:不记录二进制日志文件及记录位置
1:以change master to的方式记录位置,可用于恢复后直接启动从服务器
2:以change master to的方式记录位置,但默认为被注释
假如全备份语句为:CHANGE MASTER TO MASTER_LOG_FILE=’MySQL-bin.0000011′, MASTER_LOG_POS=106;
我们可以删除MySQL-bin.0000011前的二进制日志文件(不建议)
mysql< purge binary logs to 'mysql-ibn.0000011';
< show binary logs;
< delete from tutors where age >80; #修改数据
< flush logs; #刷新二进制文件,出现mysql-bin.0000012文件
记录周一的增量: mysqlbinlog mysql-bin.000011 > /root/monday.sql
到了周二:
< insert into tutors values ('123'); #接着修改数据
这时数据库出现问题,我们需要进行数据库的恢复
mysql -u root -p < /root/alldatabase.sql
mysql -u root -p < /root/monday.sql
mysqlbinlog mysql-bin.0000012 > temp.sql
mysql -u root -p < temp.sql
后两行相当于:mysqlbinlog mysql-bin.0000012 | mysql -u root -p
利用mysqldump工具,在myasim引擎中,只能进行温备(只能读,不能写)
在innodb引擎中,可以进行热备(可读可写)
一、工作场景
(1)MySQL数据库每晚12:00自动完全备份。
(2)某天早上上班,9点的时候,一同事犯晕drop了一个数据库!
(3)需要紧急恢复!可利用备份的数据文件以及增量的binlog文件进行数据恢复。
二、数据恢复思路
(1)利用全备的sql文件中记录的CHANGE MASTER语句,binlog文件及其位置点信息,找出binlog文件中增量的那部分。
(2)用mysqlbinlog命令将上述的binlog文件导出为sql文件,并剔除其中的drop语句。
(3)通过全备文件和增量binlog文件的导出sql文件,就可以恢复到完整的数据。
参考博客:http://blog.51cto.com/13452945/2065670
http://www.cnblogs.com/kevingrace/p/5904800.html
mysql的性能优化
https://blog.csdn.net/weixin_38112233/article/details/79054661
mysql读写分离踩过的坑
要解决主从时延的问题
1.延迟问题
读写分离不能回避的问题之一就是延迟,可以考虑Google提供的SemiSyncReplicationDesign补丁。
由于数据延迟问题的存在,当应用程序在Master 上进行数据更新,然后又立刻需要从数据库中读取数据时,这时候如果应用程序从Slave上取数据(这也是当前Web开发的常规做法),就可能出现读取不到期望的数据,造成程序运行异常。
在解决了读写分离后,如何解决同步延迟呢?
方法是在Master上增加一个自增表,这个表仅含有1个的字段。当Master接收到任何数据更新的请求时,均会触发这个触发器,该触发器更新自增表中的记录。如下图所示:
mysql_proxy_write
由于Count_table也参与Mysq的主从同步,因此在Master上作的 Update更新也会同步到Slave上。当Client通过Proxy进行数据读取时,Proxy可以先向Master和Slave的 Count_table表发送查询请求,当二者的数据相同时,Proxy可以认定 Master和Slave的数据状态是一致的,然后把select请求发送到Slave服务器上,否则就发送到Master上。如下图所示:
mysql_proxy_read
通过这种方式,就可以比较完美的结果MySQL的同步延迟不可控问题。之所以所“比较完美”,是因为这种方案double了查询请求,对 Master和Slave构成了额外的压力。不过由于Proxy与真实的Mysql Server采用连接池的方式连接,因此额外的压力还是可以接受的。