Mysql作为web数据库,对于越来越大的数据存储,主从复制、分区技术和SQL语句优化,对于提高访问量有很大的帮助。
主服务器首先对远程服务器建立一个授权用户,可以在从服务器上登录主服务器的数据库。
Mysql〉grant all on *.* to [email protected] identified by "123";
Mysql>use mysql
Mysql>select user,password,host from user; //查看用户情况
测试:从服务器登陆,可以看到内容和主服务器是一样的
Mysql的bin-log日志是记录与数据的增删改查有关的数据库语句。于是bin-log可以作为数据库恢复的文件来使用,也是mysql能够主从复制的基础。
Vi /etc/my.cnf
Log-bin=mysql-bin //增加这个语句,重启mysql即可
Mysql>show variables like ‘%bin%’;
mysql>flush logs; //此时就会多一个新的bin-log日志
mysql>show master status; //查看目前使用的bin-log日志
mysql>reset master; //清空所有日志
备份数据库:测试数据库名为test,表为t。
Mysqldump –uroot –p test –l –F > ‘/tmp/test.sql’
-L锁定表,-F是刷新bin-log日志,这样便可以用刷新之前的日志进行恢复到备份时刻
Mysql>insert into t values(1); //插入新纪录
Mysq>flush logs;
Mysql>drop table t; //删除表
恢复数据库
Mysql test </tmp/test.sql
如果要恢复数据库备份后那段时间的记录,就需要恢复bin-log日志
Mysqlbinlog mysql-00002.bin |mysql –uroot –p test
下图是bin-log的日志内容我们可以看到它是包含position点的。恢复日志也可以指定position点。--stop-position=“193”.
Mysql主从复制的优点:
1.如果主服务器出现问题,可以快速切换到从服务器提供服务
2.可以在从服务器上执行查看操作,降低主服务器的访问压力
3.可以在从服务器上执行备份,以避免备份期间影响主服务器的服务
Mysql>grant all slave on *.* to [email protected] identified by “123”;
Vi /etc/my.cnf
Log-bin=mysql-bin //开启log-bin功能
Server-id=1 //指定server ID
Service mysql restart
Mysql>show master status; //查看是否开启和bin ID
Vi /etc/my.cnf
指定主服务器ip和server id(这里id要不为1),以及主服务器的端口和连接主服务器的用户名和密码,开启bin-log,然后重启mysql服务器,同步之前要确保主从服务器有相同的数据库名和表结构。
Mysql>show slave status\G
这里要保证两个yes选项,第一个slave_io_running 为yes表示可以成功从主服务器上读取binlog日志并写入从服务上,第二个slave_Sql_running为yes表示可以成功读取本机binlog日志同步数据。可以看到它们也具有相同的bin-log。
如果数据无法同步:
如果是slave_io_running失败,要检查一下从数据库能否登陆主数据,然后检查从数据库是否和主数据有一致的数据库和表结构。
如果是slave_sql_running失败,要检查从服务是否启动和配置文件。
如slave stop; set global sql_slave_skip_counter=1;slave start.
当mysql的数据记录超过千万或上亿条纪录时,数据的性能会出现下降,这时就要用到分表分区技术或优化sql语句的方法来提高数据库的使用效率。
分表技术通常有垂直分表和水平分表,垂直分表是对数据库字段进行分表;水平分表是对数据记录进行分表。垂直分表技术复杂,不易操作,水平分表更常用。
水平分表可以将一个表分成多个表,但是如果多个表使用不同的表名,则查询语句要更改,于是引入了分区分表的概念,它不改变表名。
分区分表是在逻辑层进行水平分表,对与应用程序而言,它依然是一张表。Mysql5.1中,它有5钟分区类型:
Range分区:基于属于一个给定的连续区间的列值,把匹配的多行分配给相应分区
List分区:类似range分区,区别在于list分区是基于列值匹配一个离散值集合中的某个值来进行选择
Hash分区:基于用户定义的表达式的返回值进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算,这个函数可以包含mysql中有效的,产生非负整数值的任何表达式
Key分区:类似于hash分区,区别在于key分区只支持计算一列或多列,且mysql服务器提供其自身的哈希函数
查看mysql的版本信息:mysql>status;
查看是否支持分区技术:mysql>show plugins; //看到partion选项
例1:假定如下的表,该表有20加音像店的职员记录,这二十家的音像编号从1到20,如果采用range分区为4个小分区,如何实现呢?
Mysql>create table employees(
>id int not null,
>fname varchar(30),
>lname varchar(30),
>hired date not null default ‘1970-01-01’,
>separated date not null default ‘9999-12-31’,
>job_code int not null,
>store_id int not null
>)
>partition by range(store_id)(
>partition p0 values less than(6),
>partition p1 values less than(11),
>partition p2 values less than(16),
>partition p3 values less than(21),
>);
根据store_id(店号)进行分区,less than根据店号ID进行分区。
如果要按离职时间进行分区可以使用:
>partition by range(year(separated))(
>partition p0 values less than(1991),
>partition p1 values less than(1996),
>partition p2 values less than(2001),
>partition p3 values less than maxvalue,
>); //使用year()函数转为整形
List分区类似于range分区,但他是根据离散值来分区。
例3.还是该表保存有20家音像店,编号从1到20,而这20家音像店分布在四个区域:
>partition by list(store_id)(
>partition pnorth values in (3,5,6,9,17),
>partition peast values in(1,2,10,11,19,20),
>partition pwest values in(4,12,13,14,18),
>partition pcentral values in( 7,8,15,16),
>);
Hash分区主要是用来保护数据在预先确定数目的分区中平均分布。他可以在基于用户定义的表达式的返回值来进行选择分区,该表达式使用将要插入到表中的这些行的列值进行计算
例4:把不同时期的入职时间进行hash
>Partition by hash(year(hired))
>partitions 4
>;
例5、
可以查看到数库分为5个分区,从0到4,在加上frm文件和par文件,供12个文件。
不同分区技术对比
创建索引,也是一种提高数据库效率的方法。
Mysql>Create index idx_id on t2(id);
Mysql>show index from t2;
首先建立一个表,插入几个数据进行测试,然后使用select into t2 select * from t2 ;进行倍数的增加
再打开一个终端,发现是均匀分配数据的。还有一个发现,有时索引比数据更大,造成空间浪费。
插入1000万行记录,然后看时间和大小,1000万条记录。
查看数据库文件大小
存储过程:是一种通过创建语句,然后调用数据库的方法。
通过存储过程灌入800万条测试数据库
Mysql>delimiter //
Mysql>create procedure load_part_tab()
Begin
Declare v <8000000
Do
Insert into part_tab
Values (v,’testing partitions’,adddate(‘2000-01-01’,(rand(v)*36520)mod 3652));
Set v=v+1;
End while;
End
//
Mysql>delimiter;
分别插入数值和字段“testingpartition“和随机时间。
Mysql>? procedure //查看存储帮助
再创建一个两个表,一个使用分区实例,一个不使用分区实例,然后调用存储过程即可完成内容的插入,最后测试。
Mysql分区实例:
Mysql>create table part_tab (c1 int default null,c2 varchar(30) default null, c3 date default null ) engine=myisam
Partition by range(year(c3))(
Partition p0 values less than(2000),
Partition p1values less than(2001),
Partition p2 values less than(2002),
Partition p3 values less than(2003),
Partition p4 values less than(2004),
Partition p5 values less than(2005),
Partition p6 values less than(2006),
Partition p7 values less than(2006),
Partition p8 values less than(2007),
Partition p9 values less than(2008),
Partition p10 vlues less than maxvalue);
创建未分区实例:
Mysql> create table no_part_tab (c1 int default null,c2 varchar(30) default null, c3 date default null ) engine=myisam;
利用存储过程插入数据:
Mysql>call load_part_tab();
Mysql>inset into no_part_tab select * from part_tab;
测试:SQL性能
Mysql>select count(*) from part_tab where c3>date ‘2000-01-01’ and c3<’2000-12-31’; //大约0.55秒
Mysql> select count(*) from no_part_tab where c3>date ‘2000-01-01’ and c3<’2000-12-31’; //大约5秒
相差10倍,说明分区技术可以有效降低查询时间。
检索范围查看到,分区表查找范围明显很小为79万。
如果创建索引再查看结果:
Mysql>create index_c3 on no_part_tab(c3);
Mysql> create index_c3 on part_tab(c3);
测试:
发现创建索引之后测试访问时间发现明显二者都显著变小,说明索引也是一种优化查询的方法。下图是查找未索引的字段。
Innodb是一种事务型的表存储引擎。对于innodb表,要区分两个概念。共享表空间和独占表空间。
共享表空间:某个数据库的所有表的数据,存储在一个数据文件中,默认的文件名为ibdata1,初始化为10MB。
独占表空间:每一个表都将会生成独立的文件来存储数据,每一个表除了一个frm文件还有一个.ibd文件。
只有把innodb设置成独立表空间以后,才能创建innodb的表分区。
Vi /etc/my.cnf //将innodb_file_per_table =1,重启mysql即可
然后创建表,指定引擎和分区情况,查看数据文件即可看到分区文件顺利生成。