环境: Rails 3.0.3
Rails中判断表是否存在,表的某个字段是否存在都提供了API,但是如何判断数据库存在,没有提供api
可以使用下面的方法判断出来:
> ActiveRecord::Base.connection.execute("USE INFORMATION_SCHEMA") # 连接mysql INFORMATION_SCHEMA 数据库 >ActiveRecord::Base.connection.execute("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'db'").to_a =>[["db"]] # 存在db >ActiveRecord::Base.connection.execute("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'db1'").to_a =>[] # 不存在db1
最终环境 : ubuntu 10.10 + ruby 1.8.7 + rails 2.3.5 + mysql 5.1
换了新工作,重新搭建开发环境,鉴于之前mysql遇到问题,总是不好解决,束手无策,甚至找不到 mysql 安装哪去了,所以这次主要想编译安装mysql,这样有利于了解mysql
1,下载ruby1.8.7 (http://www.ruby-lang.org/en/news/2010/08/16/ruby-1-8-7-p302-is-released/)
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p302.tar.bz2
2,安装依赖的库
sudo apt-get install build-essential sudo apt-get install autoconf sudo apt-get install zlib1g-dev sudo apt-get install openssl libssl-dev
3,编译安装ruby
tar -jxvf ruby-1.8.7-p302.tar.bz2 cd ruby-1.8.7-p302/ autoconf ./configure --prefix=/usr/local/system/ruby make sudo make install
4,ruby 加到PATH 中
vim ~/.bashrc export PATH="$PATH:/usr/local/system/ruby/bin"
5,ruby -v
安装rubygems(http://rubyforge.org/frs/?group_id=126&release_id=43601)
1,下载
wget http://rubyforge.org/frs/download.php/70696/rubygems-1.3.7.tgz
2,解压
tar -zvxf rubygems-1.3.7.tgz
3,安装
cd rubygems-1.3.7/ wxianfeng@ubuntu:~/Desktop/rubygems-1.3.7$ ruby setup.rb ERROR: While executing gem ... (Errno::EACCES) Permission denied - /usr/local/system/ruby/lib/ruby/site_ruby/1.8/rubygems wxianfeng@ubuntu:~/Desktop/rubygems-1.3.7$ sudo ruby setup.rb [sudo] password for wxianfeng: sudo: ruby: command not found 改变权限 cd /usr/local sudo chmod -R 777 system/ 再次安装就ok了,不然你以后还会遇到这个问题
4,gem -v
安装rails 2.3.5
>gem install rails -v 2.3.5 --no-ri --no-rdoc
编译安装 mysql
1,下载并且编译安装
download (http://downloads.mysql.com/archives.php?p=mysql-5.1) 从archives 找到 ,注意下载的是source包
sudo apt-get install g++ libncurses5-dev # 安装依赖的库 sudo groupadd mysql # 建立mysql用户组 sudo useradd -g mysql mysql # 添加用户mysql tar -zvxf mysql-5.1.51.tar.gz cd mysql-5.1.51/ ./configure --prefix=/usr/local/system/mysql --with-charset=utf8 --with-collation=utf8_general_ci --with-extra-charsets=latin1(all) --with-plugins=innobase(all) # config 很重要,括号里是或者 make sudo make install sudo cp support-files/my-medium.cnf /etc/my.cnf # 配置文件
注意mysql sock文件安默认装在tmp路径下 /tmp/mysql.sock,编译的时候 —with-plugins=all 建议加上 不然你会发现编译后不支持innodb引擎,那就麻烦了!
2, 初始化数据库并修改目录权限
cd /usr/local/system/mysql sudo bin/mysql_install_db --user=mysql sudo chown -R root . sudo chown -R mysql /usr/local/system/mysql/var sudo chgrp -R mysql .
3,启动mysql
bin/mysqld_safe --user=mysql & netstat -antup | grep 3306 sudo cp /usr/local/system/mysql/share/mysql/mysql.server /etc/init.d/mysql sudo killall mysqld # kill 刚刚启动的mysql sudo /etc/init.d/mysql start|stop|restart|status # 重启mysql
4,添加PATH
>vim ~/.bashrc export PATH="$PATH:/usr/local/system/mysql/bin" wxianfeng@ubuntu:/usr/local/system/mysql/bin$ mysql --version mysql Ver 14.14 Distrib 5.1.51, for pc-linux-gnu (i686) using EditLine wrapper
5, 修改mysql root 密码
>sudo /etc/init.d/mysql start --skip-grant-tables >mysql -uroot -p mysql >update user set password=passsword('root') where user='root'; 重启mysql 就ok了 root 账户的密码为root
6,怎么判断我的mysql是编译安装的
wxianfeng@ubuntu:~$ mysql --version mysql Ver 14.14 Distrib 5.1.51, for pc-linux-gnu (i686) using EditLine wrapper
如果你是apt-get 安装的话就显示 for ubuntu-linux-gnu
yum 安装的话就显示 for redhat-linux-gnu 了
遇到的问题:
1,
>mysql -uroot -p
Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)
>mysql -uroot -p --socket=/tmp/mysql.sock 可以启动,所以是sock问题 后来发现 my.cnf 有两个配置文件,/etc/mysql/my.cnf 多了一个这个,里面sock路径指定不一样所致,rename 掉 >mv /etc/mysql/my.cnf /etc/mysql/my_cnf.bak
2,
Starting MySQL. * Manager of pid-file quit without updating file. 错误
wxianfeng@ubuntu:/usr/local/system/shell$ /etc/init.d/mysql start Starting MySQL. * Manager of pid-file quit without updating file.
需要加sudo
3,查看mysql data目录
root@ubuntu:/usr/local/system/mysql/var# ps auxf | grep mysql root 25756 0.0 0.0 4012 764 pts/3 S+ 15:32 0:00 | \_ grep --color=auto mysql root 25000 0.0 0.0 4904 1400 ? S 14:22 0:00 /bin/sh /usr/local/system/mysql/bin/mysqld_safe --datadir=/usr/local/system/mysql/var --pid-file=/usr/local/system/mysql/var/ubuntu.pid mysql 25106 0.0 0.8 119652 16568 ? Sl 14:22 0:00 \_ /usr/local/system/mysql/libexec/mysqld --basedir=/usr/local/system/mysql --datadir=/usr/local/system/mysql/var --user=mysql --log-error=/usr/local/system/mysql/var/ubuntu.err --pid-file=/usr/local/system/mysql/var/ubuntu.pid --socket=/tmp/mysql.sock --port=3306
可以看出在var下 ,注意 var目录的用户是 mysql ,必须root用户才能cd进入
sudo su # 切换到root用户
4,启动rails project报错:因为mysql gem的版本过高的原因
uninitialized constant MysqlCompat::MysqlRes (NameError) >sudo apt-get install libmysqlclient-dev >gem install mysql -v=2.7 --no-ri --no-rdoc
SEE:
http://blog.sitearth.com/ubuntu%E4%B8%8A%E6%90%AD%E5%BB%BAlamp%E7%8E%AF%E5%A2%83%E7%AC%94%E8%AE%B0%E2%80%94%E2%80%94mysql%E6%BA%90%E7%A0%81%E5%AE%89%E8%A3%85%E5%8F%8A%E9%85%8D%E7%BD%AE/
http://51jsp.cn/html/ror/2010/0327/14859.html
see:http://qichunren.javaeye.com/blog/577556
环境:centos 5.5 + mysql 5.0
最近给我的blog生成了pdf文档,发现上了服务器后生成的pdf中文都是乱码,本地都是好的,后来发现我进入mysql 的console中select出来的中文都是乱码,解决之:
查看字符编码:
mysql> SHOW VARIABLES LIKE 'charac%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 8 rows in set (0.00 sec)
这个是正确的设置,原来查看出来的是latin1,即mysql自带的编码集,发现rails中只要你database.yml中设置了encoding:utf8就可以了,哪怕mysql的character_set_*是latin1,那么你存入数据库中的中文也不是乱码,so,rails中设置encoding非常之重要
那么如何解决mysql console中乱码,修改配置文件:
>vim /etc/my.cnf
[mysqld]
default-character-set = utf8
[client]
default-character-set = utf8
mysqld 和 clcient 区域中配置上面的两句即可
然后重启mysql
如果出现 unknown variable 'default-character-set=utf8'
,可能是 mysql版本是 5.5 以上, 在 mysqld 部分改为:
character_set_server=utf8
环境:linode(16G磁盘) + centos 5.5
前些天一直收到 linode的 磁盘IO 警告的邮件,工作繁忙 , 也没有管它,殊不知 隔了一天 我的blog 不能访问了 , ssh进入linode跟踪log ,mysql报 Got error 28 from storage engine ,后来查出是磁盘已经用完的原因,解决过程如下:
1,查看磁盘占用情况
[root@li165-150 system]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda 16G 15G 0 100% /
发现磁盘已经占满 , 接下来需要找出谁占用了这么大的空间
[root@li165-150 system]# cd / [root@li165-150 /]# du -sh * 5.4M bin 4.0K boot 32K dev 13M etc 56M home 21M lib 16K lost+found 4.0K media 4.0K mnt 4.0K opt 15G var
发现 var 目录占用最大 ,继续跟踪 cd /var , du -sh * 最后跟踪到是 /var/log/maillog 占用最大 ,足足有 14G,删除之
>rm /var/log/maillog
此时 使用 df -h 查看空间占用情况 还是 15G , 需要释放删除的空间
2,重启 centos ,释放空间
登入 linode.com reboot 你的centos , 就可以 释放删除文件的磁盘了 , 还有 就是发现 linode。com的显示的磁盘占用情况依然还是 100% ,实际我进入系统查看 , 空闲磁盘已经有 9G了
3,重启之前已经开启的服务
/etc/init.d/mysqld start # 启动mysql /usr/local/system/nginx/sbin/nginx # 启动nginx thin start -C /etc/thin/thin.yml # 启动thin /etc/init.d/httpd start # 启动 apache /etc/init.d/postfix start # 启动邮件相关服务 /etc/init.d/dovecot start /etc/init.d/saslauthd start cd /usr/local/system/www/short_url/lib nohup ruby mongoshort.rb -e production & # 启动sinatra cd /usr/local/system nohup mongodb/bin/mongod --dbpath=/usr/local/system/mongodb/data & # 启动mongodb cd /usr/local/system svnserve -d -r vcs # 启动svn server
在启mongodb的时候 , 报文件锁定 , 无法启动 , 需要 repair 一下
mongodb/bin/mongod --repair
4,ok,大功告成
See:
http://www.mongodb.org/display/DOCS/Durability+and+Repair
http://www.fufuok.com/mysql-got-error-28.html
想让你的本地mysql数据库某个表迅速产生大量数据吗,例如 500 万条 , 来进行性能测试 , 我就遇到了这个情况 , 导入过程如下:
测试环境 : windows xp + mysql 5.1
myisam 引擎的表导入:
表结构如下:
members(id,name.password,city,created_at,updated_at)
id是int型,name,password,city 都是varchar型,created_at,updated_at 是 datetime类型,其中 city字段 有索引
1,关闭表的索引
ALTER TABLE members DISABLE KEYS;
关闭keys , 会在导入过程中对新的record不建索引,加快导入速度.
2,导入数据
load data infile 'E:/members.txt' into table members fields terminated by "," optionally enclosed by '"' lines terminated by "\r\n" (name,password,city,created_at,updated_at);
fields terminated by “,” 字段分隔符, lines terminated by “\r\n” 行分隔符, 注意windows下的默认行换行符是 \r\n ,UNIX 下的换行符是 \n , optionally enclosed by ‘"’ 对于 字符型字段 加双引号 , 不是指字符型的,例如int 则不加双引号
members.txt 文件内容形式:
"wxianfeng","wxianfeng","beijing","2010-06-30 00:07:45","2010-06-30 00:07:48" "kaili","kaili","suzhou","2010-06-30 00:07:45","2010-06-30 00:07:48"
最后 (name,password,city,created_at,updated_at) 指定依次导入的字段
那么 members.txt 又是怎么来的呢 , 你可以导出一个表瞧瞧就知道了 , 导出方法如下:
select * from members into outfile 'E:/members.txt' fields terminated by "," optionally enclosed by '"';
那么下面就是你有什么办法快速生成上面的 members.txt 了,我用ruby写了个脚本生成了 500 万条数据:
# members(name,password,city,created_at,updated_at) citys = %w(beijing shanghai guangzhou nanjing wuhan xihan hangzhou dalian jinan hefei) arr = ('0'..'9').to_a + ('a'..'z').to_a File.open("E:/members_1.txt","a+") do |file| 2_000_000.times do |ele| p "generate --- #{ele}" str = '' 5.times { |t| str << arr[rand(arr.size)] } time = Time.now.strftime("%Y-%m-%d %H:%M:%S") file.write("\"#{str}\",\"#{str}\",\"#{citys[rand(citys.size)]}\",\"#{time}\",\"#{time}\"\n") end end
最后生成 500 万条数据后 , 导入的速度非常之快 , 据官方介绍 load data infile 的方式是sql导入速度的20倍 ,快的根本原因我想应该还是生成的文件小,纯粹数据的形式,容易快速加载到内存里
3,再开启 KEYS
ALTER TABLE members ENABLE KEYS;
innodb 引擎表的导入:
1,导入前关闭表的唯一性校验
SET UNIQUE_CHECKS=0;
2,关闭自动提交
innodb型的表是事务安全的,每一条sql执行后都会自动提交,关闭后将会提交导入速度
SET AUTOCOMMIT=0;
3,导入数据
和之前 myisam 表的导入方式相同, 但是有一点不同的是,生成members .txt 数据的时候 ,把id也生成,因为innodb类型的表是按照主键顺序保存的,对于给定有序的文本,比没有顺序的要快的多
4,开启之前的 唯一性和事务自动提交功能
SET UNIQUE_CHECKS=1; SET AUTOCOMMIT=1;
最主要的还是要使用 load data infile 的导入方式,无论怎样, 你不要使用 单条 insert ,一条一条的插入, 这样网络io开销会巨大,速度很慢 , 实在不行,你应该构造 一个insert into 多个value的方式来导入 , 也会快很多,这个就是默认的mysqldump导出表数据所用的方法,还可以发现 在导入之前 , 它进行了锁表:
LOCK TABLES `members` WRITE; insert into members values (......),(......),(....) UNLOCK TABLES;
ref:
参考了 网易出的那本mysql书籍
环境:ubuntu 10.10 + mysql 5.1 + rails 3.0.3 + ruby 1.9.2
今天创建组合索引时,遇到下面的错误:
Mysql2::Error: Specified key was too long; max key length is 1000 bytes: CREATE UNIQUE INDEX `unique_users_name_password` ON `users` (`name`, `password`)
问题重现:
表结构:(数据库,表,字段都是utf-8 编码,myisam引擎)
users: name: varchar(255) password: varchar(255)
Rails创建索引:
add_index :users , [:name,:password] , :unique=>true , :name=>"unique_users_name_password" # mysql 唯一索引可以指定多个字段
执行就 Error 了 ,
Google 后 ,得到是 myisam 表组合索引 有长度限制 , 总长度不能 超过 1000 bytes
计算下上面的 总长度(bytes)
utf8 编码 : 1 char = 3 bytes
255 * 3 + 255 * 3 = 1530 bytes
果然大于1000 了 ,修改 name 的字段长度:
change_column :users ,:name , :string , :limit => 100
再建索引 就 ok了……
那么 表改为 innodb 引擎呢 ,不error 了 ,但是 会抱下面的warning
warning:Specified key was too long;max key length is 767 bytes.
why?
原来 innodb表的组合索引的长度 是 767 bytes , 比 myisam 的还少 ,但是 innodb的可以顺利 建索引,超过767长度的部分 建不被索引,前面的取 前缀索引 ,这里 要注意!
建议;
1,表 设置为 innodb
2,建字段时,一定要根据实际情况,限制长度,在 rails migration中就是 加 :limit 参数
see:
http://blog.fesite.com/2009/02/09/mysql-specified-key-was-too-long-max-key-length-is-1000-bytes/
http://samyubw.blog.51cto.com/978243/223773