看到推送的消息说,mysql 5.7 ga版本出来了,说是有更好的性能,对于多核CPU、固态硬盘、锁有着更好的优化。在这一版本里面,mysql也终于有了json数据结构,虽说现在还不能跟mongodb这样的文档性数据库做比拟,但这已经是关系型数据库的一大改进了。
mysql5.7 ga版本说是10 26号才发布下载地址. 那我们就先测试下最新的rc版本。最近的版本是mysql5.7.8,mysql在5.7.8的时候,才加入了json功能。 对于这样的新鲜功能,我总是那么的好奇。 今天就体验下mysql5.7.8 json的功能,还要看python MySQLdb对于这样的json支持程度。
1. 安装相关工具
yum -y install gcc-c++ ncurses-devel cmake make perl gcc autoconf automake zlib libxml libgcrypt libtool bison
2. 清理环境, 以前要把以前的mysql-sever mysql-* 卸载个干净。
3. mysql源码包下载
mysql5.7.8源码包下载:
http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.8-rc.tar.gz
如果mysql的版本有更新,可以自己找找递增的版本
http://mirrors.sohu.com/mysql/
4. 创建mysql用户, 组及目录
# groupadd mysql
# useradd -g mysql -d /home/mysql mysql
# mkdir /data/mysql/
5. 注意事项
从MySQL 5.7.5开始Boost库是必需的,下载Boost库,在解压后复制到/usr/local/boost目录下,然后重新cmake并在后面的选项中加上选项 -DWITH_BOOST=/usr/local/include/boost/
新版本mysql-5.7.8需求boost_1_57_0, 下载地址如下:
wget -c http://git.typecodes.com/libs/ccpp/boost_1_57_0.tar.bz2 tar -jxf boost_1_57_0.tar.bz2 && cd boost_1_57_0/ ./bootstrap.sh ./b2 stage threading=multi link=shared ./b2 install threading=multi link=shared cd ~ && rm -rf boost_1_57_0*
boost安装之后,咱们开始编译mysql,首先需要cmake
cmake \ -DCMAKE_BUILD_TYPE:STRING=Release \ -DCMAKE_INSTALL_PREFIX:PATH=/usr/local/mysql \ -DCOMMUNITY_BUILD:BOOL=ON \ -DENABLED_PROFILING:BOOL=ON \ -DENABLE_DEBUG_SYNC:BOOL=OFF \ -DINSTALL_LAYOUT:STRING=STANDALONE \ -DMYSQL_DATADIR:PATH=/data/mysql \ -DMYSQL_MAINTAINER_MODE:BOOL=OFF \ -DWITH_EMBEDDED_SERVER:BOOL=ON \ -DWITH_EXTRA_CHARSETS:STRING=all \ -DWITH_SSL:STRING=bundled \ -DWITH_UNIT_TESTS:BOOL=OFF \ -DWITH_ZLIB:STRING=bundled \ -DENABLE_DTRACE=OFF \ -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/include/boost/
CMAKE_INSTALL_PREFIX:指定MySQL程序的安装目录,默认/usr/local/mysql
DEFAULT_CHARSET:指定服务器默认字符集,默认latin1
DEFAULT_COLLATION:指定服务器默认的校对规则,默认latin1_general_ci
ENABLED_LOCAL_INFILE:指定是否允许本地执行LOAD DATA INFILE,默认OFF
WITH_COMMENT:指定编译备注信息
WITH_xxx_STORAGE_ENGINE:指定静态编译到mysql的存储引擎,MyISAM,MERGE,MEMBER以及CSV四种引擎默认即被编译至服务器,不需要特别指定。
WITHOUT_xxx_STORAGE_ENGINE:指定不编译的存储引擎
SYSCONFDIR:初始化参数文件目录
MYSQL_DATADIR:数据文件目录
MYSQL_TCP_PORT:服务端口号,默认3306
MYSQL_UNIX_ADDR:socket文件路径,默认/tmp/mysql.sock
编译安装
# make && make install
以root初始化操作时要加–user=mysql参数,生成一个随机密码(注意保存登录时用),密码是放在/home/mysql/.mysql_secret文件里面的。
# cd /home/mysql
# bin/mysqld –initialize –user=mysql –basedir=/user/local/mysql –datadir=/data/mysql/
8. 创建配置文件
拷贝配置文件模板为新的mysql配置文件,
cd /usr/local/mysql/support-files;cp my-default.cnf /etc/my.cnf
可按需修改新的配置文件选项, 不修改配置选项, mysql则按默认配置参数运行.
如下是我修改配置文件/etc/my.cnf, 用于设置编码为utf8以防乱码
[mysqld]
character_set_server=utf8
init_connect=’SET NAMES utf8′
[client]
default-character-set=utf8
9. 配置mysql服务开机自动启动
拷贝启动文件到/etc/init.d/下并重命令为mysqld
# cp /user/local/mysql/support-files/mysql.server /etc/init.d/mysqld
增加执行权限
# chmod 755 /etc/init.d/mysqld
这时候mysql一切都完毕了,我们启动mysql。
/etc/init.d/mysqld start
这里在贴下,编译mysql5.7.8的时候,遇到的一些问题。
第一个问题
新版的mysql在默认初始化的时候,会在你的家目录下生成一个含有密码的文件。一开始没好好看文档,以前跟5.6一样空密码,结果搞得很头疼。 另外在使用mysql_install_db 进行新实例初始化会提示下面信息:
./bin/mysql_install_db –user=mysql –datadir=/data/mysql/
[ERROR] Failed to execute –bootstrap –datadir=/data/mysql –lc-messages-dir=/usr/share/mysql –lc-messages=en_US
— server log begin —
mysqld: [Warning] –bootstrap is deprecated. Please consider using –initialize instead
— server log end —
可以看到提示 mysql_install_db 已经不再推荐使用了,建议改成 mysqld –initialize 完成实例初始化,如果想以前那样空密码模式也是可以了,需要–initialize-insecure 参数,指定初始化数据库,并且设为空密码。
改成 mysqld –initialize 后,如果 datadir 指向的目标目录下已经有数据文件,则会有类似提示:
./bin/mysqld –user=mysql –basedir=/usr/local/mysql –datadir=/data/mysql –initial –initialize-insecure
[ERROR] –initialize specified but the data directory has files in it. Aborting.
[ERROR] Aborting
因此,需要先确保 datadir 目标目录下是空的,避免误操作破坏已有数据。如果想强制初始化,那么直接删除data目录就可以了。
另外,在初始化时如果加上 –initial-insecure,则会创建空密码的 root@localhost 账号,否则会创建带密码的 root@localhost 账号,密码直接写在 log-error 日志文件中(在5.6版本中是放在 ~/.mysql_secret 文件里,更加隐蔽,不熟悉的话可能会无所适从)
./bin/mysqld –user=mysql –basedir=/user/local/mysql –datadir=/data/mysql –initialize
[Warning] Insecure configuration for –secure-file-priv: Current value does not restrict location of generated files. Consider setting it to a valid, non-empty path.
初始化完毕后,如果没使用新版本的客户端登入,还会报告类似下面的错误:
mysql -uroot -p
Enter password:
ERROR 1862 (HY000): Your password has expired. To log in you must change it using a client that supports expired passwords.
上面的错误提示意思是需要用当前版本的客户端登入。需要确定你的环境变量是否有冲突,也就是说,别的文件的mysql bin 还存在。
遇到的第二个问题:
CMake Error at cmake/boost.cmake:76 (MESSAGE):
You can download it with -DDOWNLOAD_BOOST=1 -DWITH_BOOST=<directory>
This CMake script will look for boost in <directory>. If it is not there,
it will download and unpack it (in that directory) for you.
If you are inside a firewall, you may need to use an http proxy:
export http_proxy=http://example.com:80
Call Stack (most recent call first):
cmake/boost.cmake:228 (COULD_NOT_FIND_BOOST)
CMakeLists.txt:452 (INCLUDE)
— Configuring incomplete, errors occurred!
解决的方法,删除以前的boost,下载boost,并重新编译安装就可以了。 另外cmake的时候,加入boost的相关参数 cmake -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost
既然安装成功,那么我们开始使用python操作mysqldb .
创建表:
CREATE TABLE `blogs` ( `doc` json DEFAULT NULL, `updated` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入数据:
import MySQLdb import json class MysqlStore(object): def __init__(self,mysql_dict): self.host = mysql_dict['host'] self.port = mysql_dict['port'] self.db = mysql_dict['db'] self.user = mysql_dict['user'] self.pw = mysql_dict['pw'] self._get_connection() self._get_cursor() def _get_connection(self): self.conn = MySQLdb.connect(host=self.host, user=self.user,passwd=self.pw,db=self.db,charset="utf8") self.conn.autocommit(True) def _get_cursor(self): self.cursor = self.conn.cursor() def close(self): self._conn.close() config = { 'host':'127.0.0.1', 'user':'root', 'port':3306, 'pw':'xiaorui.cc', 'db':'json' } new_blog = { 'page_id': '1', 'title': 'welcome to xiaorui.cc', } mysql = MysqlStore(config) sql = "INSERT INTO blogs (doc) VALUES (%s)" mysql.cursor.execute(sql,(json.dumps(new_blog),))
查询数据.
select = (
"SELECT JSN_EXTRACT(doc, '.page_id'), "
"JSN_EXTRACT(doc, '.title') "
"FROM blogs "
"WHERE JSN_CONTAINS(doc, JSN_OBJECT('page_id', %s))"
)
mysql.cursor.execute(select, ('1',))
for row in mysql.cursor.fetchall():
print("%s | %s" % (row[0], row[1]))
话说,MySQLdb原本就支持json,换句话说,对于MySQLdb来说,他发送的都是sql语句而已,原本就没有就不用接口的适配。 原本以为json是新结构,MySQLdb不支持,在github中提了一个issue问题。
总结, python mysqldb,pymysql都支持mysql的json结构。
用mongodb
lai’zi 来自