2016年10月

msyql唯一性约束

创建表的时候指定唯一性约束

create table if not exists `category`
(
`category_id` int unsigned primary key not null,
`category_name` char(10) unique
)engine=innodb charset=utf8;

如果插入进 category 表的数据的 category_namecategory 表的中 category_name 字段中已经存在,就会报错

mysql> insert into `category` value (1,'c1');
Query OK, 1 row affected (0.06 sec)

mysql> insert into `category` value (2,'c1');
ERROR 1062 (23000): Duplicate entry 'c1' for key 'category_name'

默认约束就不记录了

mysql外键

指定外键,注意,表的存储引擎药选择支持外键的存储引擎,不然无效

create table `category`
(
`category_id` int unsigned primary key not null,
`category_name` char(10)
)engine=innodb charset=utf8;
create table `book`
(
`book_id` int unsigned primary key,
`book_name` char(10),
`category_id` int unsigned not null,
constraint fk_1 foreign key(`category_id`) references `category`(`category_id`)#指定 `category` 表的 `category_id` 字段为 当前表的 `category_id` 字段的外键
) engine=innodb charset=utf8;

如果插入进 book 表的数据的 category_id 不在 category 表的中 category_id 字段中,就会报如下的错误

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`book`, CONSTRAINT `fk_1` FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`))

如果直接删除外键表的话会报错

mysql> drop table if exists `category`;
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails

需要先删除创建了外键约束的表,或者删除外键约束

drop table if exists `book`;
drop table if exists `category`;

(转载)mysql binlog日志自动清理及手动删除

转载自 http://blog.csdn.net/atco/article/details/24259333
说明:
当开启mysql数据库主从时,会产生大量如mysql-bin.00000* log的文件,这会大量耗费您的硬盘空间。
mysql-bin.000001
mysql-bin.000002
mysql-bin.000003
mysql-bin.000004
mysql-bin.000005

有三种解决方法:1.关闭mysql主从,关闭binlog;2.开启mysql主从,设置expire_logs_days;3.手动清除binlog文件,> PURGE MASTER LOGS TO ‘MySQL-bin.010′;

实现:

1.关闭mysql主从,关闭binlog

# vim /etc/my.cnf  //注释掉log-bin,binlog_format
# Replication Master Server (default)
# binary logging is required for replication
# log-bin=mysql-bin
# binary logging format - mixed recommended
# binlog_format=mixed

然后重启数据库

2.重启mysql,开启mysql主从,设置expire_logs_days

# vim /etc/my.cnf  //修改expire_logs_days,x是自动删除的天数,一般将x设置为短点,如10
expire_logs_days = x  //二进制日志自动删除的天数。默认值为0,表示“没有自动删除”

此方法需要重启mysql,附录有关于expire_logs_days的英文说明

当然也可以不重启mysql,开启mysql主从,直接在mysql里设置expire_logs_days

> show binary logs;
> show variables like '%log%';
> set global expire_logs_days = 10;

3.手动清除binlog文件

# /usr/local/mysql/bin/mysql -u root -p
> PURGE MASTER LOGS BEFORE DATE_SUB(CURRENT_DATE, INTERVAL 10 DAY);   //删除10天前的MySQL binlog日志,附录2有关于PURGE MASTER LOGS手动删除用法及示例
> show master logs;

也可以重置master,删除所有binlog文件:

# /usr/local/mysql/bin/mysql -u root -p 
> reset master;  //附录3有清除binlog时,对从mysql的影响说明

附录:

1.expire_logs_days英文说明

Where X is the number of days you’d like to keep them around. I would recommend 10, but this depends on how busy your MySQL server is and how fast these log files grow. Just make sure it is longer than the slowest slave takes to replicate the data from your master.
Just a side note: You know that you should do this anyway, but make sure you back up your mysql database. The binary log can be used to recover the database in certain situations; so having a backup ensures that if your database server does crash, you will be able to recover the data.

2.PURGE MASTER LOGS手动删除用法及示例,MASTER和BINARY是同义词

> PURGE {MASTER | BINARY} LOGS TO 'log_name'
> PURGE {MASTER | BINARY} LOGS BEFORE 'date'

删除指定的日志或日期之前的日志索引中的所有二进制日志。这些日志也会从记录在日志索引文件中的清单中被删除MySQL BIN-LOG 日志,这样被给定的日志成为第一个。
实例:

> PURGE MASTER LOGS TO 'MySQL-bin.010';  //清除MySQL-bin.010日志
> PURGE MASTER LOGS BEFORE '2008-06-22 13:00:00';   //清除2008-06-22 13:00:00前binlog日志
> PURGE MASTER LOGS BEFORE DATE_SUB( NOW( ), INTERVAL 3 DAY);  //清除3天前binlog日志BEFORE,变量的date自变量可以为'YYYY-MM-DD hh:mm:ss'格式。

3.清除binlog时,对从mysql的影响

如果您有一个活性的从属服务器,该服务器当前正在读取您正在试图删除的日志之一,则本语句不会起作用,而是会失败,并伴随一个错误。不过,如果从属服务器是休止的,并且您碰巧清理了其想要读取的日志之一,则从属服务器启动后不能复制。当从属服务器正在复制时,本语句可以安全运行。您不需要停止它们。

mysqldump 命令基本使用(转载)

转载自 : http://www.cnblogs.com/feichexia/p/MysqlDataBackup.html

mysqldump常用于MySQL数据库逻辑备份。

1、各种用法说明

A. 最简单的用法:
mysqldump -uroot -pPassword [database name] > [dump file]

上述命令将指定数据库备份到某dump文件(转储文件)中,比如:

mysqldump -uroot -p123 test > test.dump

生成的test.dump文件中包含建表语句(生成数据库结构哦)和插入数据的insert语句。

B. --opt

如果加上--opt参数则生成的dump文件中稍有不同:

 . 建表语句包含drop table if exists tableName

 . insert之前包含一个锁表语句lock tables tableName write,insert之后包含unlock tables
C. 跨主机备份
 使用下面的命令可以将host1上的sourceDb复制到host2的targetDb,前提是host2主机上已经创建targetDb数据库:
mysqldump --host=host1 -uroot -pPassword --opt sourceDb| mysql --host=host2 -C targetDb -uroot -pPassword 

-C指示主机间的数据传输使用数据压缩

D. 只备份表结构
mysqldump --no-data --databases mydatabase1 mydatabase2 mydatabase3 > test.dump

将只备份表结构。--databases指示主机上要备份的数据库。如果要备份某个MySQL主机上的所有数据库可以使用--all-databases选项,如下:

mysqldump --all-databases > test.dump
E. 从备份文件恢复数据库
mysql [database name] < [backup file name]

2、结合Linux的cron命令实现定时备份

比如需要在每天凌晨1:30备份某个主机上的所有数据库并压缩dump文件为gz格式,那么可在/etc/crontab配置文件中加入下面代码行:

30 1 * * * root mysqldump -u root -pPASSWORD --all-databases | gzip > /mnt/disk2/database_`date '+%m-%d-%Y'`.sql.gz

前面5个参数分别表示分钟、小时、日、月、年,星号表示任意。date '+%m-%d-%Y'得到当前日期的MM-DD-YYYY格式。

3、一个完整的Shell脚本备份MySQL数据库示例

#vi /backup/backup.sh

#!bin/bash
cd /backup
echo "You are in backup dir"
mv backup* /oldbackup
echo "Old dbs are moved to oldbackup folder"
File = backup-$Now.sql
mysqldump -u user -p password database-name > $File
echo "Your database backup successfully completed"

上面脚本文件保存为backup.sh,并且系统中已经创建两个目录/olcbackup和/backup。每次执行backup.sh时都会先将/backup目录下所有名称为backup开头的文件移到/oldbackup目录。

  为上述脚本制定执行计划如下:
#crontab -e
30 1 * * * /backup.sh

4、mysqldump全量备份+mysqlbinlog二进制日志增量备份

从mysqldump备份文件恢复数据会丢失掉从备份点开始的更新数据,所以还需要结合mysqlbinlog二进制日志增量备份。确保my.ini或者my.cnf中包含下面的配置以启用二进制日志,或者mysqld ---log-bin:

[mysqld]
log-bin=mysql-bin

mysqldump命令必须带上--flush-logs选项以生成新的二进制日志文件:

mysqldump --single-transaction --flush-logs --master-data=2 > backup.sql

这样生成的增量二进制日志文件比如为mysql-bin.000003,那么恢复数据时如下:

shell> mysql -uroot -pPwd < backup_sunday_1_PM.sql
shell> mysqlbinlog mysql-bin.000003 | mysql -uroot -pPwd

此外mysqlbinlog还可以指定--start-date、--stop-date、--start-position和--stop-position参数,用于精确恢复数据到某个时刻之前或者跳过中间某个出问题时间段恢复数据,直接摘录MySQL文档说明中相关内容如下:

5.9.3.1. 指定恢复时间
对于MySQL 4.1.4,可以在mysqlbinlog语句中通过--start-date和--stop-date选项指定DATETIME格式的起止时间。举例说明,假设在今天上午10:00(今天是2005年4月20日),执行SQL语句来删除一个大表。要想恢复表和数据,你可以恢复前晚上的备份,并输入:
mysqlbinlog --stop-date="2005-04-20 9:59:59" /var/log/mysql/bin.123456 \
     | mysql -u root -pmypwd
该命令将恢复截止到在--stop-date选项中以DATETIME格式给出的日期和时间的所有数据。如果你没有检测到几个小时后输入的错误的SQL语句,可能你想要恢复后面发生的活动。根据这些,你可以用起使日期和时间再次运行mysqlbinlog:
mysqlbinlog --start-date="2005-04-20 10:01:00" /var/log/mysql/bin.123456 \
     | mysql -u root -pmypwd \

在该行中,从上午10:01登录的SQL语句将运行。组合执行前夜的转储文件和mysqlbinlog的两行可以将所有数据恢复到上午10:00前一秒钟。你应检查日志以确保时间确切。下一节介绍如何实现。

5.9.3.2. 指定恢复位置
也可以不指定日期和时间,而使用mysqlbinlog的选项--start-position和--stop-position来指定日志位置。它们的作用与起止日选项相同,不同的是给出了从日志起的位置号。使用日志位置是更准确的恢复方法,特别是当由于破坏性SQL语句同时发生许多事务的时候。要想确定位置号,可以运行mysqlbinlog寻找执行了不期望的事务的时间范围,但应将结果重新指向文本文件以便进行检查。操作方法为:

mysqlbinlog --start-date="2005-04-20 9:55:00" --stop-date="2005-04-20 10:05:00" \
      /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
该命令将在/tmp目录创建小的文本文件,将显示执行了错误的SQL语句时的SQL语句。你可以用文本编辑器打开该文件,寻找你不要想重复的语句。如果二进制日志中的位置号用于停止和继续恢复操作,应进行注释。用log_pos加一个数字来标记位置。使用位置号恢复了以前的备份文件后,你应从命令行输入下面内容:
mysqlbinlog --stop-position="368312" /var/log/mysql/bin.123456 \
    | mysql -u root -pmypwd 

mysqlbinlog --start-position="368315" /var/log/mysql/bin.123456 \
    | mysql -u root -pmypwd \ 
上面的第1行将恢复到停止位置为止的所有事务。下一行将恢复从给定的起始位置直到二进制日志结束的所有事务。因为mysqlbinlog的输出包括每个SQL语句记录之前的SET TIMESTAMP语句,恢复的数据和相关MySQL日志将反应事务执行的原时间。

CentOS release 6.6 lvm扩容

服务器分区容量不够,需要扩容,公司使用的是虚拟机,直接调整了虚拟机的磁盘容量,然后嗨需要做如下的处理才能达到效果,记录下
参考网址 : http://blog.sina.com.cn/s/blog_967817f20102v2a6.html http://blog.sina.com.cn/s/blog_ac85574f01014wwc.html
分区

fdisk /dev/sda

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n #新建分区
# 选择分区类型
Command action
   e   extended
   p   primary partition (1-4)
p # 主分区类型
#分区号,根据具体情况设置即可
Partition number (1-4): 3
# 开始扇区,默认即可
First cylinder (16579-39162, default 16579): 
# 结束扇区,默认的话就是使用全部
Last cylinder, +cylinders or +size{K,M,G} (16579-39162, default 39162): 
# 设置创建的分区的类型为 lvm
t
# 选择分区,就选择上面的分区
Partition number (1-4): 3
# 输入lvm的dai m8e, 
Hex code (type L to list codes): 8e
#保存退出
w

重启服务器
lvm 操作

# 查看 pv 
pvdisplay
  --- Physical volume ---
  PV Name               /dev/sda2
  VG Name               VolGroup
  PV Size               126.51 GiB / not usable 2.00 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              32386
  Free PE               0
  Allocated PE          32386
  PV UUID               eFSO1Y-tyey-pa0K-0vea-uW7p-FmTh-TO0gEG
# 创建刚刚创建的分区为 pv 
pvcreate /dev/sda3
# 查看 pv 
pvdisplay
  --- Physical volume ---
  PV Name               /dev/sda2
  VG Name               VolGroup
  PV Size               126.51 GiB / not usable 2.00 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              32386
  Free PE               0
  Allocated PE          32386
  PV UUID               eFSO1Y-tyey-pa0K-0vea-uW7p-FmTh-TO0gEG

  --- Physical volume ---
  PV Name               /dev/sda3
  VG Name               
  PV Size               173.00 GiB / not usable 4.06 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              44286
  Free PE               254
  Allocated PE          44032
  PV UUID               gSth8U-LXJl-3FA1-YGju-6J02-e4v0-ek8j2Y
# 把 pv 加入原有的 vg
vgextend VolGroup /dev/sda3
#查看 lv 
lvdisplay 
  --- Logical volume ---
  LV Path                /dev/VolGroup/lv_root
  LV Name                lv_root
  VG Name                VolGroup
  LV UUID                eefIxD-Sps3-44v1-3DRB-ODSA-byuq-6QHZe6
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2015-01-26 15:11:02 +0800
  LV Status              available
  # open                 1
  LV Size                50.00 GiB
  Current LE             56832
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0
# 添加容量 
lvresize -L +172GB /dev/mapper/VolGroup-lv_root
#查看 lv 
lvdisplay 
  --- Logical volume ---
  LV Path                /dev/VolGroup/lv_root
  LV Name                lv_root
  VG Name                VolGroup
  LV UUID                eefIxD-Sps3-44v1-3DRB-ODSA-byuq-6QHZe6
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2015-01-26 15:11:02 +0800
  LV Status              available
  # open                 1
  LV Size                222.00 GiB
  Current LE             56832
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0

修改文件系统的容量 ,注意这里的device是虚拟设备lv的名称,并不是sdax这样的物理设备了,我的环境下药修改的是分目录的容量,对应的是/dev/VolGroup/lv_root,在 /etc/fstab 文件里面可以查看 或者用 lvdisplay查看

vim /etc/fstab
/dev/mapper/VolGroup-lv_root /                       ext4    defaults        1 1
UUID=c1da8f6f-e67f-4f0f-90de-2883035385d7 /boot                   ext4    defaults        1 2
/dev/mapper/VolGroup-lv_home    /home   ext4    grpquota,usrquota,rw    0       2
/dev/mapper/VolGroup-lv_swap swap                    swap    defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
#修改
fsadm resize /dev/VolGroup/lv_root 222G