[转帖]MYSQL:1003错误信息3-7-0--搜狗_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 12 | 回复: 0   主题: [转帖]MYSQL:1003错误信息3-7-0--搜狗        上一篇   下一篇 
majijia
注册用户
等级:上等兵
经验:120
发帖:3
精华:0
注册:2012-7-2
状态:离线
发送短消息息给majijia 加好友    发送短消息息给majijia 发消息
发表于: IP:您无权察看 2018-5-9 11:26:14 | [全部帖] [楼主帖] 楼主

ar xvzf mysql-max-4.1.10a-pc-linux-gnu-i686.tar.gz
[root@fxs001 local]# ll mysql-max-4.1.10a-pc-linux-gnu-i686* -d
drwxr-xr-x 14 503 users 4096 Mar 6 2005 mysql-max-4.1.10a-pc-linux-gnu-i686
-rw-r--r-- 1 root root 37537397 Oct 24 14:08 mysql-max-4.1.10a-pc-linux-gnu-i686.tar.gz


建立mysql组、用户,设定 /usr/local/mysql 目录,初始化权限等:

groupadd mysql
useradd -g mysql mysql
cd /usr/local
ln -s /usr/local/mysql-max-4.1.10a-pc-linux-gnu-i686 mysql
cd mysql
scripts/mysql_install_db --user=mysql
chown -R root .
chown -R mysql data
chgrp -R mysql .


拷贝MYSQL提供的样例配置文件 my-large.cnf,设置mysql 的启动脚本。

cd support-files/
root@fxs001 support-files]# cp my-large.cnf /etc/my.cnf
[root@fxs001 support-files]# cp mysql.server /etc/init.d/mysqld


启动mysql。

Service mysqld start
ps xuwww |grep mysql
root 30253 0.0 0.2 4380 1248 pts/0 S 14:59 0:00 /bin/sh ./bin/mysqld_safe --datadir=/usr/local/mysql/data --pid-file=/usr/local/mysql/data/fxs001.fxs.livedoor.cn.pid
[root@fxs001 support-files]# netstat -antp |grep 3306
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 30279/mysqld
[root@fxs001 support-files]#


已经看到 MYSQL进程启动了。

启动后确认
登陆mysql

[root@fxs001 data]# /usr/local/mysql/bin/mysql -uroot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 4.1.10a-max-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>


建立一个数据库、建立一个数据表。

mysql> create database fxtest ;
Query OK, 1 row affected (0.01 sec)
mysql> use fxtest
Database changed
mysql> show tables ;
Empty set (0.00 sec)
mysql> create table FX_TEST1 (Code varchar(20),Name varchar(20)) ;
Query OK, 0 rows affected (0.00 sec)
mysql> show tables ;
+------------------+
| Tables_in_fxtest |
+------------------+
| FX_TEST1 |
+------------------+
1 row in set (0.00 sec)
mysql> show create table FX_TEST1 ;
+----------+----------------------------------------------------------------------------------------+
| Table | Create Table |
+----------+----------------------------------------------------------------------------------------+
| FX_TEST1 | CREATE TABLE `FX_TEST1` (
`Code` varchar(20) default NULL,
`Name` varchar(20) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+----------+----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
[root@fxs001 data]# ll /tmp/mysql.sock
srwxrwxrwx 1 mysql mysql 0 Oct 24 14:59 /tmp/mysql.sock


设置成随系统自动启动
因为刚才已经执行过:cp mysql.server /etc/init.d/mysqld 。

[root@fxs001 data]# chkconfig --list mysqld
service mysqld supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add mysqld')
[root@fxs001 data]# chkconfig --add mysqld
[root@fxs001 data]# chkconfig --list mysqld
mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@fxs001 data]# chkconfig --level 123456 mysqld off
[root@fxs001 data]# chkconfig --level 345 mysqld on
[root@fxs001 data]# chkconfig --list mysqld
mysqld 0:off 1:off 2:off 3:on 4:on 5:on 6:off
[root@fxs001 data]#


MYSQL权限设置
1.设置口令
刚刚在一台Linux机器上进行了MYSQL服务的安装,在验证服务正常后,第一个要做的任务就应该是设置密码,MYSQL的密码是保存在 mysql 库中的 user 表中。

/usr/local/mysql/bin/mysql –uroot
mysql> select Host,user,password From user ;
+------------------------+------+----------+
| Host | user | password |
+------------------------+------+----------+
| localhost | root | |
| fxs001.fxs.livedoor.cn | root | |
| fxs001.fxs.livedoor.cn | | |
| localhost | | |
+------------------------+------+----------+
4 rows in set (0.00 sec)


此状态是刚刚安装过后的样子,没有密码,因此登陆不需要指定密码。

mysql> update user set password =PASSWORD('123456') ;
mysql> select Host,user,password From user ;
+------------------------+------+-------------------------------------------+
| Host | user | password |
+------------------------+------+-------------------------------------------+
| localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| fxs001.fxs.livedoor.cn | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| fxs001.fxs.livedoor.cn | | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| localhost | | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
+------------------------+------+-------------------------------------------+
4 rows in set (0.00 sec)
mysql> flush privileges ;
Query OK, 0 rows affected (0.00 sec)


在刷新之前其实还是可以用 无密码方式登陆的,刷新是更新MYSQL的缓存。

mysql> delete from user where user='' ;
Query OK, 2 rows affected (0.00 sec)


删除掉这个无关的默认用户,这个用户的存在就是风险。

mysql> flush privileges ;
Query OK, 0 rows affected (0.00 sec)
mysql> select Host,user,password From user ;
+------------------------+------+-------------------------------------------+
| Host | user | password |
+------------------------+------+-------------------------------------------+
| localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| fxs001.fxs.livedoor.cn | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
+------------------------+------+-------------------------------------------+
2 rows in set (0.00 sec)
[root@fxs001 mysql]# /usr/local/mysql/bin/mysql -uroot
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)


试一下,不能登了。

[root@fxs001 mysql]# /usr/local/mysql/bin/mysql -uroot -p123456
Welcome to the MySQL monitor. Commands end with ; or \g.


带上密码就可以了。

2.修改密码的三种方法
方法一:使用mysqladmin

格式:mysqladmin -u用户名 -p旧密码 password 新密码

例1:E:\mysql>mysqladmin -uroot password root
注:因为开始时root没有密码,所以-p旧密码一项就可以省略了。
例2:再将root的密码改为root123。

E:\mysql>mysqladmin -uroot -proot password root123


方法二:直接更新 user 表

mysql>UPDATE user SET password=PASSWORD("test123") WHERE user='test';
mysql> FLUSH PRIVILEGES;
mysql> SET PASSWORD FOR test=PASSWORD('test123');
mysql> FLUSH PRIVILEGES;


方法三:使用 grant

格式:grant 权限 on 数据库.表格| 其他 to 用户@主机 IDENTIFIED BY 口令

例1:给test用户在本地localhost 所有权限(除了GRANT OPTION),口令为 test

(相当于修改了test 用户的口令)
mysql>grant all on *.* to test@localhost identified by "test";


等同于

mysql>grant all on *.* to test @localhost identified by PASSWORD " *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 ";


3.增删修查用户的权限
语法:

Grant privileges (Columns) on what to account identified by ‘password’ with grant options or resource management options ;


MySQL权限系统保证所有的用户只执行允许做的事情。当你连接MySQL服务器时,你的身份由你从那儿连接的主机和你指定的用户名来决定。

连接后发出请求后,系统根据你的身份和你想做什么来授予权限。

MySQL在认定身份中考虑的是【你的主机名】+【用户名字】,以此来判断不同的连接来源是不同的用户,并根据这些信息来赋予这个连接不同的操作权限。

MySQL存取控制包含2个阶段:

阶段1:服务器检查是否允许你连接。(登陆阶段)

阶段2:假定你能连接,服务器检查你发出的每个请求。看你是否有足够的权限实施它。例如,如果你从数据库表中选择(select)行或从数据库删除表,服务器确定你对表有SELECT权限或对数据库有DROP权限。(每个操作阶段)

MYSQL的权限控制是通过 mysql库中表:user,db,host, tables_priv和columns_priv 一起控制的,

在MYSQL启动时,系统将这些信息读入到内存中,如果有新的变动(做了Grant或者Revoke命令后)后,必须运行命令 flush privileges 。

以下举例来说明:

grant all on *.* to 'testu'@'10.4.5.233' identified by '123456' ;


将所有数据库中的所有表的所有权限赋给 testu用户(必须从10.4.5.233 这台机器上登陆mysql)。

但是登陆后不能设置其他用户的权限。

grant select on *.* to 'testu2'@'%' identified by '123456' ;


设置一个可以从任何地方登陆进来的只可以访问任何表的用户testu2,注意是“只读”.

和 select 相对应的有:INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES 。

grant all on *.* to 'testu3'@'10.4.5.0/255.255.255.0' identified by '123456' ;


设定一个可以从 10.4.5. 网段登陆进来的可以做任何事情的帐户。

grant all on *.* to 'testu4'@'10.4.5.201 ' identified by '123456' with grant option ;


给 testu4 用户一个超级管理员权限

看一下 testu4有哪些权限:

mysql> show grants ;
| GRANT ALL PRIVILEGES ON *.* TO 'testu4'@'10.4.5.201' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' WITH GRANT OPTION |
+---------------------------------------------------------------------------------------------------------------------------
revoke grant option on *.* from 'testu4'@'10.4.5.201' ;


收回 testu4得超级管理员得权限。

….


4.忘记MYSQL超级用户密码root后的处理。
如果 MySQL 正在运行,首先杀之: killall -TERM mysqld。

启动 MySQL :bin/safe_mysqld --skip-grant-tables &

就可以不需要密码就进入 MySQL 了。

然后就是

>use mysql
>update user set password=password("new_pass") where user="root";
>flush privileges;


重新杀 MySQL ,用正常方法启动 MySQL 。

系统配置。
MYSQL启动关闭方式

启动命令有两种方式:

1,直接使用MYSQL提供的命令:bin/safe_mysqld &

2,使用mysql提供的脚本 support-files/mysql.server 脚本,拷贝到系统的相关目录,可以比较灵活的自动启动等。

配置文件的存放路径
MYSQL 的配置文件可以存放在多个路径,但是彼此之间是有覆盖关系的,所以在使用的时候要消息,不要防止多个,也不要乱放。

1,/etc/my.cnf
2,Data_directory/my.cnf


3,defaults-extra-file 是在启动的时候指定的。

4,~/my.cnf


后面的配置文件选项会覆盖前面的选项,如果一个配置项在上述四个地方都能找到,那么将用最后一个设定值。

在实际使用中,一台服务器一般只安装一个 MYSQL,配置文件一般放置在 /etc/my.cnf 中。

数据目录存放路径、文件意义
数据目录
二进制包的默认路径为/usr/local/mysql/data目录,或者是你可以在启动的时候用--datadir指定数据目录,需要注意的几个地方,

1),不要在数据目录自己手动创建文件,mysql删除数据库的时候是根据扩展名来删除的,如果有的话,数据库不会被删除,show databases可以看到 。

2)Mysql的数据库和数据表名可由数字、字符串以及下划线、$组成,最多64个字符,表的最大尺寸myisam表为4G(max_rows,avg_row_length来定义),innodb表类型默认页面尺寸是16K,源码编译时可选择8~64K的大小和磁盘有关

show create table tbl_name
show create database db_name


数据目录主要内容
Hostname.pid 这个MYSQL 的进程号

Hostname.err MYSQL 的错误日志,启动、运行中如果有错误会打印到此。

Hostname.log 故障诊断又叫常规查询日志,记录用户操作的每一步,在实系统中会增长的非常的快,因此慎用。在my.cnf配置文件中加 log 配置项。

Hostname-slow.log 慢查询日志,可以用命令mysqldumpslow 来查看内容,也可以直接观察。

log-slow-queries 增加这个选项表示要生成慢查询日志。

log-queries-not-using-indexes 没有使用索引的SQL也记录到慢查询日志中。

long_query_time 慢,到底多慢才记录。(秒)默认值是 10 秒。

Hostname.nnn --log-update 。变更日志,已经建议取消的选项。


Hostname-bin.nnn 二进制变更文件,(update,delete,update,truacate 等SQL语句的汇集)

flush-logs
max_binlog_size 1G
reset master
purge master logs to ‘’


binlog-do-db= 只记录某个数据库的变更

binlog-ignore-db=


Hostname-bin.index 存放当前的binlog的文件名。

MYSQL的表类型的特点

 MyISAM


HEAP 内存表,

Merge表

BDB表

InnoDB 表

配置文件
配置文件的位置
/etc/my.cnf 文件。

配置文件中每一项的含义
这个因为选项太多了,这里只以我们实际系统的两个例子作为参考吧:

[mfx@o07-c4 mysqldatabackup]$ more /etc/my.cnf |grep -vE "^$|^#"
[client] --客户端的连接信息。
port = 3306
socket = /tmp/mysql.sock
[mysqld]
port = 3306 #指定服务启动端口
socket = /tmp/mysql.sock
skip-locking
key_buffer=512M
max_allowed_packet = 1M
max_connections=1024
table_cache=1024
sort_buffer=128M
net_buffer_length = 8K
myisam_sort_buffer_size = 8M
default-character-set=ujis
record_buffer=64M
log-bin
server-id = 1
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[isamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[myisamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout


另一个MySQL的配置,主要包含了挺多的 innoDB类型的数据库表

[4a-o07-b4:root/1002]#more /etc/my.cnf |grep -vE "^$|^#"
[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
port = 3306
socket = /tmp/mysql.sock
skip-locking
key_buffer = 128M
query_cache_size=32M
max_connections= 200
table_cache = 512
log_error=/usr/local/mysql/data/111mysql.err
innodb_buffer_pool_size = 512M
innodb_log_buffer_size = 8M
server-id = 1
log-bin
[mysqldump]
quick
max_allowed_packet = 32M
[mysql]
no-auto-rehash
[isamchk]
key_buffer = 8M
sort_buffer_size = 8M
[myisamchk]
key_buffer = 8M
sort_buffer_size = 8M
[mysqlhotcopy]
interactive-timeout


MYSQL基本的命令
常用实用程序

 mysql


登陆进入操作控制台的命令,导入数据也是这个命令。

mysql –uroot –p123456 –e “show variables”
mysql –uroot –p123456 mysqldb <MYSQLDB_20071024.SQL
mysqladmin


有着丰富的MYSQL管理功能

create databasename Create a new database
debug Instruct server to write debug information to log
drop databasename Delete a database and all its tables
extended-status Gives an extended status message from the server
flush-hosts Flush all cached hosts
flush-logs Flush all logs
flush-status Clear status variables
flush-tables Flush all tables
flush-threads Flush the thread cache
flush-privileges Reload grant tables (same as reload)
kill id,id,... Kill mysql threads
password new-password Change old password to new-password, MySQL 4.1 hashing.
old-password new-password Change old password to new-password in old format.
ping Check if mysqld is alive
processlist Show list of active threads in server
reload Reload grant tables
refresh Flush all tables and close and open logfiles
shutdown Take server down
status Gives a short status message from the server
start-slave Start slave
stop-slave Stop slave
variables Prints variables available
mysqlbinlog


查看二进制变更日志的SQL语句。可用于在增量备份的时候使用。

mysqlbinlog fxs001-bin.000018 |mysql -uroot -p123456 fxtest
mysqlbinlog fxs001-bin.000018 |more
mysqldump


将数据库、数据表导成一个个 SQL语句形式的文件。

--no-create-info,-t


只导出数据,而不添加 CREATE TABLE 语句。

例:[root@10 shell]# mysqldump --no-create-info wang_db >/home/shell/wang_db.sql

--no-data,-d


不导出任何数据,只导出数据库表结构。

[root@10 shell]# mysqldump --no-data wang_db >/home/shell/wang.db.sql.1


导出完整的数据(包括表的结构和数据)

[root@10 shell]# mysqldump wang_db >/home/shell/wang.db.sql.2


单独导入某个表

[root@10 shell]# mysqldump --add-drop-table wang_db wang_tb >/home/shell/wang.db.sql.3


在生产系统导出数据注意点:对一个正在运行的数据库进行备份请慎重!!

如果一定要在服务运行期间备份,请添加 –skip-opt选项,类似执行:

/usr/local/mysql/bin/mysqldump --skip-opt -uroot -p123456 mysqlfxv >mySQL.SQL


以免造成了锁表。

mysqlslowlog


后面接慢查询日志的文件名,将显示没有使用索引或者查询时间超过指定的时间的SQL。

mysqlcheck


表维护和维修程序

mysqlcheck客户端可以检查和修复MyISAM表。它还可以优化和分析表。

mysqlcheck的功能类似myisamchk,但其工作不同。主要差别是当mysqld服务器在运行时必须使用mysqlcheck,而myisamchk应用于服务器没有运行时。使用mysqlcheck的好处是不需要停止服务器来检查或修复表。

Mysqlcheck为用户提供了一种方便的使用SQL语句CHECK TABLE、REPAIR TABLE、ANALYZE TABLE和OPTIMIZE TABLE的方式。它确定在要执行的操作中使用使用哪个语句,然后将语句发送到要执行的服务器上。

有3种方式来调用mysqlcheck:

shell> mysqlcheck[options] db_name [tables]
shell> mysqlcheck[options] ---database DB1 [DB2 DB3...]s
hell> mysqlcheck[options] --all--database


如果没有指定任何表或使用---database或--all--database选项,则检查整个数据库。

例如

检查优化并修复所有的数据库用:

# mysqlcheck -A -o -r -p
Enter password:
database1 OK
database2 OK
----------


修复指定的数据库用

# mysqlcheck -A -o -r Database_NAME -p


即可

Myisamchk


myisamchk适用于MYISAM类型的数据表,而isamchk适用于ISAM类型的数据表。这两条命令的主要参数相同,一般新的系统都使用MYISAM作为缺省的数据表类型,这里以myisamchk为例子进行说明。当发现某个数据表出现问题时可以使用:

myisamchk tablename.MYI


进行检测,如果需要修复的话,可以使用:

myisamchk -of tablename.MYI


关于myisamchk的详细参数说明,可以参见它的使用帮助。需要注意的时在进行修改时必须确保MySQL服务器没有访问这个数据表,保险的情况下是最好在进行检测时把MySQL服务器Shutdown掉。

SQL命令

 (太多了,只列举一些常用的)
1, analyze table tableName. (对MyISAM,BDB 表有效)


分析一个表,将索引的最新信息收集起来,以便MYSQL 的优化器来选用。

2,check table tableName (对MyISAM和InnoDB有效)


检查这个表的索引、数据行是否有错。(有Changed,Extended,Fast,Medium,Quick 选项,默认Mediun)

3,repair table tableName (只对MyISAM表有效)


对检查出错误的表进行修复。(有Changed,Extended,Fast,Medium,Quick 选项,默认Mediun)

这个有时在数据运行一定的时间后,表数据太多,增删改频繁,偶尔会出错,到时出现这个情

况时修复数据表是必不可少的了。

4,optimize table tableName (只对MyISAM 表有效)


对一个更新、删除比较多的表的碎片进行清理、整理的过程,还收集并更新统计信息。

上面的命令基本上可以用 mysqlcheck ,myisamchk 来代替,以在 MYSQL已经停止的情况下完成这些数据表的检查修复工作。

5,backup table tableName to ‘dir_name’ ; (只对MyISAM 表有效)


它的功能其实就是把这个表的定义文件、数据问题(.frm和.MYD)拷贝到指定的目录里面。

注意一点的时候,它拷贝的时候会把这个表加上锁,如果是备份很多表的时候,锁是挨个加上去的,如果在这期间有更新的话,会造成这些表的数据不一致。

6,restore table tableName From ‘dir_name’ ;(只对MyISAM 表有效)


将指定的目录下面的文件恢复成指定的表,这个表得不存在。索引将在恢复过程中创建。

7, Change Master Master_Connect_Retry =n,Master_Host=’’,Master_log_File=’’,Master_log_pos=n, Relay_log_File=’’,Relay_log_pos=n


此上得逗号内容可以任选,作用是在 建立镜像的从服务器上设定的信息,主要有:到主服务器的哪个文件、哪个位置开始读取信息,如何连接主服务器(用户名、密码、端口)以及到已经读取过来的中继文件中的文件名和位置上进行继续同步。

一般是发生在 从服务器的同步出现问题,无法自动继续进行了,经过处理后手动干预一下后让它继续自动复制。

8,explain SQL语句。。。

是一个开发人员、系统管理人员必须掌握的一个命令,通过explain一条有些怀疑的SQL语句,能发现潜在的糟糕表现。

举个例子说明一下:

mysql> desc wangxl;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| OrderID | varchar(20) | | PRI | | |
| cc | varchar(10) | YES | | NULL | |
| ProductID | varchar(10) | YES | | NULL | |
| Trade_ID | varchar(20) | YES | | NULL | |
| Customer_ID | varchar(10) | YES | MUL | NULL | |
+-------------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
alter table wangxl add primary key (OrderID) ;
create index wangxl_i_1 on wangxl(CustomerID) ;
mysql> explain select count(*) From wangxl where OrderID='20071025ORD00392515' ;
+----+-------------+--------+-------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | wangxl | const | PRIMARY | PRIMARY | 20 | const | 1 | Using index |
+----+-------------+--------+-------+---------------+---------+---------+-------+------+-------------+
1 row in set (0.00 sec)


这是做好的情况。主建作为索引。这个表中记录有 1034 条。

再看以下:

mysql> select count(*) From wangxl where Customer_ID='515748' ;
+----------+
| count(*) |
+----------+
| 6 |
+----------+
1 row in set (0.00 sec)
mysql> explain select count(*) From wangxl where Customer_ID='515748' ;
+----+-------------+--------+------+---------------+------------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+------------+---------+-------+------+--------------------------+
| 1 | SIMPLE | wangxl | ref | wangxl_i_1 | wangxl_i_1 | 11 | const | 27 | Using where; Using index |
+----+-------------+--------+------+---------------+------------+---------+-------+------+--------------------------+
1 row in set (0.00 sec)
mysql> explain select count(*) From wangxl where trade_ID='20071025TRAD00390948' ;
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | wangxl | ALL | NULL | NULL | NULL | NULL | 1034 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)


因为TradeID 上没有索引,所以只有全表了。大家注意看 rows = 1034,实行的全表扫描。

主要看的一般rows,extra 。rows 表示这个查询(分解的对应单个查询)达到目的要进行的扫描行数。扫描的有可能是数据行,也可能是索引行。

extra 表示Mysql解决查询的详细信息,常见的有:

using filesort 表示结果的输出需要额外的再排序,一般检查Order by 后面的内容,出现这个一般不是很好。

Using where 没啥说的。

Using index 应该是挺好的。

Using temporary 出现这个得要敲警钟了。。。。取出得结果集是不是太多了。

9,kill 命令

一般结合使用的是 show processlist ,查询出哪个SQL进程在耗费资源,一直执行不完,直接 kill id号 就可以了。

不过这个一次只能kill 一个。更多的可以:

mysqladmin -uroot -p123456 processlist
mysqladmin -uroot -p123456 kill 34,35,36


有时挺有用的东西,可解你的燃眉之急。

10,lock table tableName [Read,write low_priority write]


锁住一个表防止别人写,防止别人读,防止别人读(正在读的等别人读完)

unlock table tableName 。
11,purge master logs to ‘logName’


一般配合 show master logs ; 一起使用,来删除MySQL的二进制变更文件的。

12,许许多多的show 命令。

show binlog events in 'fxs001-bin.000018' limit 100,20 \G ;


看二进制文件里面的内容。

Show create database dbName
Show create table tbName
Show grants for account
Show index from table
Show innodb status
Show master logs ;
Show master status ;
Show privileges
Show slave status


Show status 看MySQL 系统运行的状态。

Show variable


同步复制(Replication,镜象)
同步复制的功能

实现主从数据库的结构,在从服务器上将主服务器的增删改查操作通过二进制变更文件的形式快速有效的拷贝到从服务器并完成执行,使之和主服务器的数据库保持一致。

这种方式在大型网站中使用非常普遍,是解决数据库负载高分散压力的有效方法。

同步复制的配置方法
主服务器上:

对要做同步的数据库做全备份,增加一个专门用户拷贝的用户(用管理员也行)

在配置文件中添加:log-bin 和 service_id =1

从服务器上

配置文件中增加:

[mysqld]
server-id = 2
master-host = <hostname>
master-user = <username>
master-password = <password>
master-port = <port>


将主服务器的备份恢复到从服务器中。

启动从服务器。Slave start.

同步复制的监视方法
在从服务器上,show slave status \G ;

> 以下为完整信息

> Slave_IO_State       : Waiting for master to send event
> Master_Host          : 10.0.154.13
> Master_User          : root
> Master_Port          : 3306
> Connect_Retry        : 60
> Master_Log_File      : 5a-s03-a3-bin.000942
> Read_Master_Log_Pos  : 1055645666
> Relay_Log_File       : 5a-s03-a5-relay-bin.000579
> Relay_Log_Pos        : 1053248266
> Relay_Master_Log_File: 5a-s03-a3-bin.000942
> Slave_IO_Running     : Yes
> Slave_SQL_Running    : Yes
> Replicate_Do_DB      : mysqlafx
> Replicate_Ignore_DB  :
> Replicate_Do_Table   :
> Replicate_Ignore_Table:
> Replicate_Wild_Do_Table:
> Replicate_Wild_Ignore_Table:
> Last_Errno           : 0
> Last_Error           :
> Skip_Counter         : 0
> Exec_Master_Log_Pos  : 1055639194
> Relay_Log_Space      : 1053254738
> Until_Condition      : None
> Until_Log_File       :
> Until_Log_Pos        : 0
> Master_SSL_Allowed   : No
> Master_SSL_CA_File   :
> Master_SSL_CA_Path   :
> Master_SSL_Cert      :
> Master_SSL_Cipher    :
> Master_SSL_Key       :
> Seconds_Behind_Master: 0


要求:1,Read_Master_Log_Pos: =    Exec_Master_Log_Pos: ,或者相近。

2,> Slave_IO_Running     : Yes Slave_SQL_Running    : Yes


这是从服务器不断从主服务器拷贝二进制文件和执行SQL的进程。

他们都是 yes 才是正常。

主从切换
要想完成主从切换,必须删除从服务器上的几个文件,要不然不行,因为该文件中记录着一些信息。

master.info
relay.info


同步复制相关的基本命令:

 Slave start,slave stop
Show slave status \G;
Change Master to ;


Reset slave ; 在从服务器上执行,将从头开发到主服务器上取日志并在从服务器上执行。

Load data from master 到主服务器上取一份全拷贝。(好像有很多限制,直接取用全备份吧)

Restart master 在主服务器执行后,会对binlog 进行重新开始,会删掉所有得二进制日志。

Show master status 显示当前日志文件名称、日志中得位置。

Purge master logs to ‘’ 来清除二进制日志得。

Show master logs 显示二进制文件得清单。



MYSQL支持的字符集
show character set ; 显示MYSQL 能支持哪些字符集,其中也显示了默认校对字符集。

show collation ;显示支持的校对字符集。

在配置文件中添加:default-character-set=ujis 来指定默认的字符集。

优化 MYSQL
我们可以且应该优化什么?
硬件 
操作系统/软件库 
SQL服务器(设置和查询) 
应用编程接口(API) 
应用程序 

优化硬件 
如果你需要庞大的数据库表(>2G),你应该考虑使用64位的硬件结构。因为MySQL内部使用大量64位的整数,64位的CPU将提供更好的性能。 对大数据库,优化的次序一般是RAM、快速硬盘、CPU能力。更多的内存通过将最常用的键码页面存放在内存中可以加速键码的更新。  如果不使用事务安全(transaction-safe)的表或有大表并且想避免长文件检查,一台UPS就能够在电源故障时让系统安全关闭。 对于数据库存放在一个专用服务器的系统,应该考虑1G的以太网。延迟与吞吐量同样重要。

优化磁盘
为系统、程序和临时文件配备一个专用磁盘,如果确是进行很多修改工作,将更新日志和事务日志放在专用磁盘上。低寻道时间对数据库磁盘非常重要。对与大表,你可以估计你将需要log(行数)/log(索引块长度/3*2/(键码长度 + 数据指针长度))+1次寻到才能找到一行。对于有500000行的表,索引Mediun int类型的列,需要log(500000) / log(1024/3*2/(3 + 2))+1=4次寻道。上述索引需要500000*7*3/2=5.2M的空间。实际上,大多数块将被缓存,所以大概只需要1-2次寻道。 然而对于写入(如上),你将需要4次寻道请求来找到在哪里存放新键码,而且一般要2次寻道来更新索引并写入一行。 

对于非常大的数据库,你的应用将受到磁盘寻道速度的限制,随着数据量的增加呈N log N数据级递增。 

将数据库和表分在不同的磁盘上。在MySQL中,你可以为此而使用符号链接。  条列磁盘(RAID 0)将提高读和写的吞吐量。  带镜像的条列(RAID 0+1)将更安全并提高读取的吞吐量。写入的吞吐量将有所降低。  不要对临时文件或可以很容易地重建的数据所在的磁盘使用镜像或RAID(除了RAID 0)。 
在Linux上,在引导时对磁盘使用命令hdparm -m16 -d1以启用同时读写多个扇区和DMA功能。这可以将响应时间提高5~50%。 

优化操作系统
不要交换区。如果内存不足,增加更多的内存或配置你的系统使用较少内存。

不要使用NFS磁盘(会有NFS锁定的问题)。

增加系统和MySQL服务器的打开文件数量。(在safe_mysqld脚本中加入ulimit -n #)。

增加系统的进程和线程数量。

选择应用编程接口

 PERL


可在不同的操作系统和数据库之间移植。

适宜快速原型。应该使用DBI/DBD接口。

PHP


比PERL易学。使用比PERL少的资源。

通过升级到PHP4可以获得更快的速度。

C

MySQL的原生接口。

较快并赋予更多的控制。

低层,所以必须付出更多。

C++


较高层次,给你更多的时间来编写应用。

仍在开发中

ODBC


运行在Windows和Unix上。

几乎可在不同的SQL服务器间移植。

较慢。MyODBC只是简单的直通驱动程序,比用原生接口慢19%。

有很多方法做同样的事。很难像很多ODBC驱动程序那样运行,在不同的领域还有不同的错误。

问题成堆。Microsoft偶尔还会改变接口。

不明朗的未来。(Microsoft更推崇OLE而非ODBC)

JDBC


理论上可在不同的操作系统何时据库间移植。

可以运行在web客户端。

Python和其他

可能不错,可我们不用它们。

优化应用
应该集中精力解决问题。

在编写应用时,应该决定什么是最重要的:

速度

操作系统间的可移植性

SQL服务器间的可移植性

使用持续的连接。.

缓存应用中的数据以减少SQL服务器的负载。

不要查询应用中不需要的列。

不要使用SELECT * FROM table_name...

测试应用的所有部分,但将大部分精力放在在可能最坏的合理的负载下的测试整体应用。通过以一种模块化的方式进行,你应该能用一个快速“哑模块”替代找到的瓶颈,然后很容易地标出下一个瓶颈。

如在一个批处理中进行大量修改,使用LOCK TABLES。例如将多个UPDATES或DELETES集中在一起。

如果你需要更快的速度,你应该
找出瓶颈(CPU、磁盘、内存、SQL服务器、操作系统、API或应用)并集中全力解决。

使用给予你更快速度/灵活性的扩展。

逐渐了解SQL服务器以便能为你的问题使用可能最快的SQL构造并避免瓶颈。

优化表布局和查询。

使用复制以获得更快的选择(select)速度。

如果你有一个慢速的网络连接数据库,使用压缩客户/服务器协议。

不要害怕时应用的第一个版本不能完美地移植,在你解决问题时,你总是可以在以后优化它。

优化MySQL 
挑选编译器和编译选项。 
为你的系统寻找最好的启动选项。 
多用EXPLAIN SELECT、SHOW VARIABLES、SHOW STATUS和SHOW PROCESSLIST。 
了解查询优化器的工作原理。 
优化表的格式。 
维护你的表(myisamchk、CHECK TABLE、 OPTIMIZE TABLE) 
使用MySQL的扩展功能以让一切快速完成。 
如果你注意到了你将在很多场合需要某些函数,编写MySQL UDF函数。  不要使用表级或列级的GRANT,除非你确实需要。 
购买MySQL技术支持以帮助你解决问题:) 

MySQL何时使用索引
对一个键码使用>, >=, =, <, <=, IF NULL和BETWEEN 

SELECT * FROM table_name WHERE key_part1=1 and key_part2 > 5;
SELECT * FROM table_name WHERE key_part1 IS NULL;


当使用不以通配符开始的LIKE 

SELECT * FROM table_name WHERE key_part1 LIKE 'jani%'


在进行联结时从另一个表中提取行时 

SELECT * from t1,t2 where t1.col=t2.key_part


找出指定索引的MAX()或MIN()值 

SELECT MIN(key_part2),MAX(key_part2) FROM table_name where key_part1=10


一个键码的前缀使用ORDER BY或GROUP BY 

SELECT * FROM foo ORDER BY key_part1,key_part2,key_part3


在所有用在查询中的列是键码的一部分时间 
SELECT key_part3 FROM table_name WHERE key_part1=1 

MySQL何时不使用索引
如果MySQL能估计出它将可能比扫描整张表还要快时,则不使用索引。例如如果key_part1均匀分布在1和100之间,下列查询中使用索引就不是很好:  SELECT * FROM table_name where key_part1 > 1 and key_part1 < 90 
如果使用HEAP表且不用=搜索所有键码部分。 
在HEAP表上使用ORDER BY。 
如果不是用键码第一部分  SELECT * FROM table_name WHERE key_part2=1 

如果使用以一个通配符开始的LIKE  SELECT * FROM table_name WHERE key_part1 LIKE '%jani%' 
搜索一个索引而在另一个索引上做ORDER BY  SELECT * from table_name WHERE key_part1 = # ORDER BY key2 

尽量使用索引
A,在where 表达式中(列名+谓词+值),一般的谓词都是可以使用到索引的,比如:=,>=,>,<=,<, like “TT%”, 但是 <> , like “%aaa%” 一般是不会去匹配索引的。 like 里面的常量字符越长,匹配的越迅速。

比较意外的是 <> 在不同的数据库中表现不一样,MYSQL中就可以使用索引,而DB2,Oracle就不使用。。

B,如果能用别的方法替代,就不要对列名使用函数或者运算符。

例如:1) Amount=2000,2)Amount=4000/2,3)Amount/2=1000.

其中1)=2) 。但是3)非常费CPU,如果在Amount上加了索引,也将不会使用上。

C,如果有可能试试 “索引覆盖”。就是对一个Group by 语句中用到列都建立一个复合索引。

IN和EXISTS
有时候会将一列和一系列值相比较。最简单的办法就是在where子句中使用子查询。在where子句中可以使用两种格式的子查询。
第一种格式是使用IN操作符: ... where column in(select * from ... where ...); 
第二种格式是使用EXIST操作符: ... where exists (select 'X' from ...where ...); 
我相信绝大多数人会使用第一种格式,因为它比较容易编写,而实际上第二种格式要远比第一种格式的效率高。
第二种格式中,子查询以‘select 'X'开始。运用EXISTS子句不管子查询从表中抽取什么数据它只查看where子句。这样优化器就不必遍历整个表而仅根据索引就可完成工作(这里假定在where语句中使用的列存在索引)。相对于IN子句来说,EXISTS使用相连子查询,构造起来要比IN子查询困难一些。
通过使用EXIST,系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间.系统在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在在一个加了索引的临时表中。在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。这也就是使用EXISTS比使用IN通常查询速度快的原因。
同时应尽可能使用NOT EXISTS来代替NOT IN,尽管二者都使用了NOT(不能使用索引而降低速度),NOT EXISTS要比NOT IN查询效率更高。

学会使用EXPLAIN
对于每一条你认为太慢的查询使用EXPLAIN! 

mysql> explain select t3.DateOfAction, t1.TransactionID
-> from t1 join t2 join t3
-> where t2.ID = t1.TransactionID and t3.ID = t2.GroupID
-> order by t3.DateOfAction, t1.TransactionID;
+-------+--------+---------------+---------+---------+------------------+------+---------------------------------+
| table | type  | possible_keys | key   | key_len | ref       | rows | Extra              |
+-------+--------+---------------+---------+---------+------------------+------+---------------------------------+
| t1  | ALL  | NULL     | NULL  |  NULL | NULL       |  11 | Using temporary; Using filesort |
| t2  | ref  | ID      | ID   |    4 | t1.TransactionID |  13 |                 |
| t3  | eq_ref | PRIMARY    | PRIMARY |    4 | t2.GroupID    |  1 |                 |
+-------+--------+---------------+---------+---------+------------------+------+---------------------------------+


ALL和范围类型提示一个潜在的问题。 

学会使用SHOW PROCESSLIST 
使用SHOW processlist来发现正在做什么: 

+----+-------+-----------+----+---------+------+--------------+-------------------------------------+
| Id | User | Host   | db | Command | Time | State    | Info                |
+----+-------+-----------+----+---------+------+--------------+-------------------------------------+
| 6 | monty | localhost | bp | Query  | 15  | Sending data | select * from station,station as s1 |
| 8 | monty | localhost |  | Query  | 0  |       | show processlist          |
+----+-------+-----------+----+---------+------+--------------+-------------------------------------+


在mysql或mysqladmin中用KILL来杀死溜掉的线程。 

MySQL应避免的事情
用删掉的行更新或插入表,结合要耗时长的SELECT。 
在能放在WHERE子句中的列上用HAVING。 
不使用键码或键码不够唯一而进行JOIN。 
在不同列类型的列上JOIN。 
在不使用=匹配整个键码时使用HEAP表。 

给MySQL更多信息以更好地解决问题的技巧
注意你总能去掉(加注释)MySQL功能以使查询可移植: 

SELECT /*! SQL_BUFFER_RESULTS */ ...  SELECT SQL_BUFFER_RESULTS ...  将强制MySQL生成一个临时结果集。只要所有临时结果集生成后,所有表上的锁定均被释放。这能在遇到表锁定问题时或要花很长时间将结果传给客户端时有所帮助。  

SELECT SQL_SMALL_RESULT ... GROUP BY ...


告诉优化器结果集将只包含很少的行。 

SELECT SQL_BIG_RESULT ... GROUP BY ...


告诉优化器结果集将包含很多行。 

SELECT STRAIGHT_JOIN ...


强制优化器以出现在FROM子句中的次序联结表。 

SELECT ... FROM table_name [USE INDEX (index_list) | IGNORE INDEX (index_list)] table_name2


强制MySQL使用/忽略列出的索引。 

如果可能,偶尔运行一下OPTIMIZE table,这对大量更新的变长行非常重要。 
偶尔用myisamchk -a更新一下表中的键码分布统计。记住在做之前关掉MySQL。 
如果有碎片文件,可能值得将所有文件复制到另一个磁盘上,清除原来的磁盘并拷回文件。 
如果遇到问题,用myisamchk或CHECK table检查表。 
用mysqladmin -i10 precesslist extended-status监控MySQL的状态。 
用MySQL GUI客户程序,你可以在不同的窗口内监控进程列表和状态。使用mysqladmin debug获得有关锁定和性能的信息。

重要的MySQL启动选项
back_log 如果需要大量新连接,修改它。 
thread_cache_size 如果需要大量新连接,修改它。 
key_buffer_size 索引页池,可以设成很大。 
bdb_cache_size BDB表使用的记录和键吗高速缓存。 
table_cache 如果有很多的表和并发连接,修改它。 
delay_key_write 如果需要缓存所有键码写入,设置它。 
log_slow_queries 找出需花大量时间的查询。 
max_heap_table_size 用于GROUP BY 
sort_buffer 用于ORDER BY和GROUP BY 
myisam_sort_buffer_size 用于REPAIR TABLE 
join_buffer_size 在进行无键吗的联结时使用。

优化表
MySQL拥有一套丰富的类型。你应该对每一列尝试使用最有效的类型。 
ANALYSE过程可以帮助你找到表的最优类型:SELECT * FROM table_name PROCEDURE ANALYSE()。 
对于不保存NULL值的列使用NOT NULL,这对你想索引的列尤其重要。 
将ISAM类型的表改为MyISAM。 
如果可能,用固定的表格式创建表。 
不要索引你不想用的东西。 
利用MySQL能按一个索引的前缀进行查询的事实。如果你有索引INDEX(a,b),你不需要在a上的索引。 
不在长CHAR/VARCHAR列上创建索引,而只索引列的一个前缀以节省存储空间。CREATE TABLE table_name (hostname CHAR(255) not null, index(hostname(10))) 
对每个表使用最有效的表格式。 
在不同表中保存相同信息的列应该有同样的定义并具有相同的列名。 

MySQL行类型(专指IASM/MyIASM表)
如果所有列是定长格式(没有VARCHAR、BLOB或TEXT),MySQL将以定长表格式创建表,否则表以动态长度格式创建。 
定长格式比动态长度格式快很多并更安全。 
动态长度行格式一般占用较少的存储空间,但如果表频繁更新,会产生碎片。 
在某些情况下,不值得将所有VARCHAR、BLOB和TEXT列转移到另一个表中,只是获得主表上的更快速度。 
利用myiasmchk(对ISAM,pack_iasm),可以创建只读压缩表,这使磁盘使用率最小,但使用慢速磁盘时,这非常不错。压缩表充分地利用将不再更新的日志表 

MySQL高速缓存(所有线程共享,一次性分配)
键码缓存:key_buffer_size,默认8M。 
表缓存:table_cache,默认64。 
线程缓存:thread_cache_size,默认0。 
主机名缓存:可在编译时修改,默认128。 
内存映射表:目前仅用于压缩表。 
注意:MySQL没有行高速缓存,而让操作系统处理。 

MySQL表高速缓存工作原理
每个MyISAM表的打开实例(instance)使用一个索引文件和一个数据文件。如果表被两个线程使用或在同一条查询中使用两次,MyIASM将共享索引文件而是打开数据文件的另一个实例。 
如果所有在高速缓存中的表都在使用,缓存将临时增加到比表缓存尺寸大些。如果是这样,下一个被释放的表将被关闭。 
你可以通过检查mysqld的Opened_tables变量以检查表缓存是否太小。如果该值太高,你应该增大表高速缓存。

MySQL各种锁定
内部表锁定 

LOCK TABLES(所有表类型适用)
GET LOCK()/RELEASE LOCK()


页面锁定(对BDB表) 
ALTER TABLE也在BDB表上进行表锁定 
LOCK TABLES允许一个表有多个读者和一个写者。 
一般WHERE锁定具有比READ锁定高的优先级以避免让写入方干等。对于不重要的写入方,可以使用LOW_PRIORITY关键字让锁定处理器优选读取方。 

 UPDATE LOW_PRIORITY table SET value=10 WHERE id=10;


写SQL中注意的一些基本事情
尽量不要输出没有用的列。

不管是最终的输出结果还是各个分类的子查询中。

不要输出已经明确的列,造成额外负担。

每次一个数据取得都是从存储设备-〉缓冲池-〉排序和转换-〉网络传输-〉应用程序一系列过程,多了一点内容都是需要花费时间的。

另外最好不要在SQL中出现 * ,把该指明的都指明了,不要的就不要写。

写了 * 的,两年以后,这个表的字段增加了,字段顺序调整了,如果在程序里写了序号这样的,就惨了。

(这点好像和现在hibernate 的处理方法思想有点出入,没办法,不管它。只针对我们自己写的SQL)

B,尽量在每个查询中返回尽可能少的行。

这句话在一般的单个查询中是显而易见的,大伙都知道,就是说在要在where中加尽可能精确的语句来返回尽可能少的行。

但是在一个大一些的查询中,可能会忽略那样产生的影响就是巨大的。

C,对各种两个表之间的连接应该索引作为连接列。

D,用left outer join来改写not in 能获得相当的性能提高。

select * From FX_ORDER where Customer_ID='001148' and TRADE_ID not in (select Trade_ID From FX_CONTRACT where CURRENCY_PAIR='USD/JPY' and CUSTOMER_ID='001148')
dynexpln -d db2fxs -q "select O.* From FX_ORDER O left outer join (select Trade_ID,Customer_ID,CURRENCY_PAIR From FX_CONTRACT where CUSTOMER_ID='001148' and CURRENCY_PAIR='USD/JPY' ) C on O.Trade_ID=C.Trade_ID where O.Customer_ID='001148' and C.Trade_ID is null "


E,少用点 or ,它有可能会是索引失效,用union all 可以替代or ,性能上还没有损失。

Union all 是单纯的将两个结果集合并,不会重新排序。

Union 会对两个结果集重新计算然后排序输出。

加强对排序SQL语句的限制条件.排序是DB2(其他DBMS也是如此)中耗费内存非常多的操作,

G,对 Group by ,distinct 出来的结果已经是有序的了,不需要再排序。

尽量使用已经排好序的数据,免得再排序浪费资源。

H,有关绑定变量

有关绑定变量,在java 中就是使用prepareStatment来替代Statement。

一个SQL提交给MYSQL后经历词义检查、语义检查、对象检查、获取存取路径、形成最终执行计划、生成执行代码,

但是如果是两个一样的SQL(一模一样,多个空格都不行)这个过程就全部省了,使用绑定变量(有的地方可能称主机变量,就是用?来替代值,然后再设置这个值)能达到一模一样的效果,DBMS在算存取路径的时候会估算一个值来替代,这样能达到一个很好的效果。

(如果不注意这一点,那么你的系统离崩溃就不远了,这点对程序员特别重要!!)

但是也不是所有的情况都是这样,对一个SQL“长时间固定不变的环境中”,那么每次执行都是相同的SQL,这时静态变量和绑定变量方式唯一的差别是获取存取路径方式的不同,绑定方式是估算,而写成变量的方式是精确的路径。

实际中到底使用哪种?1)一般都按照绑定变量来写。2)如果在设计的时候就能明确该句在使用执行的环境,再换成静态方式。

其实 都用绑定变量这种方式来写,没有什么坏处!

I,在大表上不做GROUP BY,相反创建大表的总结表并查询它。  对于大表,或许最好偶尔生成总结表而不是一直保持总结表。

J,充分利用INSERT的默认值。 

K,为了减少各个程序中相互锁等待或者死锁的可能,对一个事务应该尽快提交。

对一个大型多进程又多线程这样的系统来说,如果没有选择一个合适粒度的业务锁将是一个灾难,如果各个应用在处理事务的过程中都存在潜在的锁竞争,那么就可以产生死锁。

如 A事务, update A where ID=’A001’,update B where ID=’B001’,提交事务.

 B事务, update B where ID=’B001’,update A where ID=’A001’,提交事务.

如果A,B两个事务有在同时运行的可能,那么就有产生死锁的情况出现,这很不好,大的程序逻辑里一定要避免这个。

  在一个异步等待的程序里面,避免出现最后才提交的情况,那样可能增加持有锁的时间,造成锁升级的可能。

理解Fx系统的业务锁。

为了能够顺利、独立、相互没有干扰的前提下每个独立的应用程序能操作一系列核心表的任务,就需要一个全局的锁,即:对某个用户同一时刻只能进行一个核心业务。

为了达到这个目的,在每个核心业务的事务开始地方,进行 

Select * From Customer where Customer_ID=? For update 的操作,

如果能得到一个锁,则程序(就叫它程序A吧)向下进行,同时也锁定住了这行记录,另一个程序B想要得到这个锁的时候就必须等待,直到程序A提交了这个事务或者回滚。

这个语句有三个地方要注意:

a),想达到锁住这一行(且只这一行)的目标时,Customer_ID必须是主键或者是唯一健的索引,否则会产生无法锁住该行(此列加了普通索引)或者锁住了整个表(没加索引列)的后果。

b),for update 是一种显式的表示要更改的含义,和直接的update 语句基本是一个含义,但它不会去更改什么,只为了得到一个更新锁(U),在持有这个锁期间其他用户还是可以读这行的,保证了正常的读操作。

但是用update语句的话,这个A事务获得的将是互斥(X)锁,在A提交(或回滚)之前B事务是连读都读不了(除非指定UR隔离级别) 。

做实验:

c),with RR 是在这一句SQL 语句中指定隔离级别而不影响整个数据库的状态。

 隔离级别的含义是:为update,delete,alter,select .. for update等这些需要独占整个表或一行的操作时不同的隔离级别确定一个 让另一个事务访问的方式也很不相同。

差别大体是:可重复读RR:锁住检索过的所有记录,读稳定性(RS):锁住检索到的所有记录,游标稳定性(CS)锁住正在更改的记录,而未提交的读(UR)级别最低,只有在更改这个表、或者删除这个表的时候才会产生锁,锁住整个表。

在MySQL中演示死锁、行锁的情况,

create table customer (Code varchar(10),Name varchar(20),Amount decimal(10,0)) Type=innoDB ;
create table score (Code varchar(10),Name varchar(20),Amount decimal(10,0)) Type=innoDB ;
insert into customer values ('001001','Name',11) ;
insert into customer values ('001002','gxlName',1) ;
insert into score values ('002001','Name',22) ;
insert into score values ('002002','waame',2) ;
alter table customer add primary key (Code) ;
alter table score add primary key (Code) ;
set @@autocommit=0 ;
SELECT @@tx_isolation;
update customer set name ='testtxt' where Code='001001' ;
update score set amount=300 where Code='001007' ;
select * From customer where code=’001001’ for update
select * From customer where Name=’Name’ for update


开启两个终端进行操作,验证锁等待的情况。

MYSQL系统优化与系统设置参数的一次调查

对mysql进行优化意味着适当地分配内存,并让mysqld了解将会承担何种类型的负载。减少磁盘访问的次数。

类似地,确保 MySQL 进程正确操作就意味着它花费在服务查询上的时间要多于花费在处理后台任务(如处理临时磁盘表或打开和关闭文件)上的时间。

记录慢速查询
在一个 SQL 服务器中,数据表都是保存在磁盘上的。索引为服务器提供了一种在表中查找特定数据行的方法,而不用搜索整个表。当必须要搜索整个表时,就称为表扫描。通常来说,您可能只希望获得表中数据的一个子集,因此全表扫描会浪费大量的磁盘 I/O,因此也就会浪费大量时间。当必须对数据进行连接时,这个问题就更加复杂了,因为必须要对连接两端的多行数据进行比较。

当然,表扫描并不总是会带来问题;有时读取整个表反而会比从中挑选出一部分数据更加有效(服务器进程中查询规划器用来作出这些决定)。如果索引的使用效率很低,或者根本就不能使用索引,则会减慢查询速度,而且随着服务器上的负载和表大小的增加,这个问题会变得更加显著。执行时间超过给定时间范围的查询就称为慢速查询。

您可以配置 mysqld 将这些慢速查询记录到适当命名的慢速查询日志中。管理员然后会查看这个日志来帮助他们确定应用程序中有哪些部分需要进一步调查。清单 1 给出了要启用慢速查询日志需要在 my.cnf 中所做的配置。

启用 MySQL 慢速查询日志

[mysqld]
; enable the slow query log, default 10 seconds
log-slow-queries
; log queries taking longer than 5 seconds
long_query_time = 5
; log queries that don't use indexes even if they take less than long_query_time
; MySQL 4.1 and newer only
log-queries-not-using-indexes


这三个设置一起使用,可以记录执行时间超过 5 秒和没有使用索引的查询。请注意有关 log-queries-not-using-indexes 的警告:您必须使用 MySQL 4.1 或更高版本。慢速查询日志都保存在 MySQL 数据目录中,名为 hostname-slow.log。如果希望使用一个不同的名字或路径,可以在 my.cnf 中使用 log-slow-queries = /new/path/to/file 实现此目的。

阅读慢速查询日志最好是通过 mysqldumpslow 命令进行。指定日志文件的路径,就可以看到一个慢速查询的排序后的列表,并且还显示了它们在日志文件中出现的次数。一个非常有用的特性是 mysqldumpslow 在比较结果之前,会删除任何用户指定的数据,因此对同一个查询的不同调用被计为一次;这可以帮助找出需要工作量最多的查询。

对查询进行缓存
一般程序严重依赖数据库,但有时却会反复执行相同的查询。每次执行查询时,数据库都必须要执行相同的工作。对查询进行分析,确定如何执行查询,从磁盘中加载信息,然后将结果返回给客户机。MySQL 有一个特性称为查询缓存,它将查询结果保存在内存中。在很多情况下,这会极大地提高性能。

虚拟系统查询缓存为:

my.cnf中添加

[4a-o07-b4:root/1054]#cat /etc/my.cnf|grep query_cache
query_cache_size=32M
mysql> show variables like '%cache%';
+------------------------------+------------+
| Variable_name | Value |
+------------------------------+------------+
| query_cache_size | 33554432 |
+------------------------------+------------+
14 rows in set (0.00 sec)


监视查询缓存

在启用查询缓存之后,重要的是要理解它是否得到了有效的使用。MySQL 有几个可以查看的变量,可以用来了解缓存中的情况。

mysql> SHOW STATUS LIKE 'qcache%';
+-------------------------+------------+
| Variable_name | Value |
+-------------------------+------------+
| Qcache_free_blocks | 5216 |
| Qcache_free_memory | 14640664 |
| Qcache_hits | 2581646882 |
| Qcache_inserts | 360210964 |
| Qcache_lowmem_prunes | 281680433 |
| Qcache_not_cached | 79740667 |
| Qcache_queries_in_cache | 16927 |
| Qcache_total_blocks | 47042 |
+-------------------------+------------+
8 rows in set (0.00 sec)
Qcache_free_blocks


缓存中相邻内存块的个数。数目大说明可能有碎片。FLUSH QUERY CACHE 会对缓存中的碎片进行整理,从而得到一个空闲块。

Qcache_free_memory


缓存中的空闲内存。

Qcache_hits


每次查询在缓存中命中时就增大。

Qcache_inserts


每次插入一个查询时就增大。命中次数除以插入次数就是不中比率;用 1 减去这个值就是命中率。在上面这个例子中,大约有 87% 的查询都在缓存中命中

Qcache_lowmem_prunes


缓存出现内存不足并且必须要进行清理以便为更多查询提供空间的次数。这个数字最好长时间来看;如果这个数字在不断增长,就表示可能碎片非常严重,或者内存很少。(上面的 free_blocks 和 free_memory 可以告诉您属于哪种情况)。

Qcache_not_cached


不适合进行缓存的查询的数量,通常是由于这些查询不是 SELECT 语句。

Qcache_queries_in_cache


当前缓存的查询(和响应)的数量。

Qcache_total_blocks


缓存中块的数量。

通常,间隔几秒显示这些变量就可以看出区别,这可以帮助确定缓存是否正在有效地使用。运行 FLUSH STATUS 可以重置一些计数器,如果服务器已经运行了一段时间,这会非常有帮助。

使用非常大的查询缓存,期望可以缓存所有东西,这种想法非常诱人。由于 mysqld 必须要对缓存进行维护,例如当内存变得很低时执行剪除,因此服务器可能会在试图管理缓存时而陷入困境。作为一条规则,如果 FLUSH QUERY CACHE 占用了很长时间,那就说明缓存太大了。

强制限制

您可以在 mysqld 中强制一些限制来确保系统负载不会导致资源耗尽的情况出现。清单 3 给出了 my.cnf 中与资源有关的一些重要设置。

清单 3. MySQL 资源设置

set-variable=max_connections=500
set-variable=wait_timeout=10
max_connect_errors = 100


连接最大个数是在第一行中进行管理的。与 Apache 中的 MaxClients 类似,其想法是确保只建立服务允许数目的连接。要确定服务器上目前建立过的最大连接数,请执行 SHOW STATUS LIKE 'max_used_connections'。

第 2 行告诉 mysqld 终止所有空闲时间超过 10 秒的连接。在 LAMP 应用程序中,连接数据库的时间通常就是 Web 服务器处理请求所花费的时间。有时候,如果负载过重,连接会挂起,并且会占用连接表空间。如果有多个交互用户或使用了到数据库的持久连接,那么将这个值设低一点并不可取!

最后一行是一个安全的方法。如果一个主机在连接到服务器时有问题,并重试很多次后放弃,那么这个主机就会被锁定,直到 FLUSH HOSTS 之后才能运行。默认情况下,10 次失败就足以导致锁定了。将这个值修改为 100 会给服务器足够的时间来从问题中恢复。如果重试 100 次都无法建立连接,那么使用再高的值也不会有太多帮助,可能它根本就无法连接。

缓冲区和缓存

MySQL 支持超过 100 个的可调节设置;但是幸运的是,掌握少数几个就可以满足大部分需要。查找这些设置的正确值可以通过 SHOW STATUS 命令查看状态变量,从中可以确定 mysqld 的运作情况是否符合我们的预期。给缓冲区和缓存分配的内存不能超过系统中的现有内存,因此调优通常都需要进行一些妥协。

打开的表缓存
1.每个表都可以表示为磁盘上的一个文件,必须先打开,后读取。

为了加快从文件中读取数据的过程,mysqld 对这些打开文件进行了缓存,其最大数目由 /etc/mysqld.conf 中的 table_cache 指定

mysql> show variables like 'table_cache%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| table_cache | 512 |
+---------------+-------+
1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables | 301 |
| Opened_tables | 893 |
+---------------+-------+
2 rows in set (0.00 sec)


看status说明目前有301给表是打开的,有893个表需要打开。

如果opened_tables随着重新运行show status命令快速增加,就说明缓存命中率不够。

如果open_tables比tabe_cache设置小很多,就说明该值太大了。

线程缓存
与表的缓存类似,对于线程来说也有一个缓存。 mysqld 在接收连接时会根据需要生成线程。在一个连接变化很快的繁忙服务器上,对线程进行缓存便于以后使用可以加快最初的连接。

mysql> show variables like 'thread_cache%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| thread_cache_size | 0 |
+-------------------+-------+
1 row in set (0.00 sec)
mysql> \q
Bye
[4a-o07-b4:root/1003]#cat /etc/my.cnf|grep thread_cache
[4a-o07-b4:root/1004]#
mysql> SHOW STATUS LIKE 'threads%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 0 |
| Threads_connected | 39 |
| Threads_created | 31287 |
| Threads_running | 1 |
+-------------------+-------+
4 rows in set (0.00 sec)


虚拟系统没有设置线程的缓存。

索引缓冲区
关键字缓冲区保存了 MyISAM 表的索引块。理想情况下,对于这些块的请求应该来自于内存,而不是来自于磁盘。

mysql> show variables like 'key_buffer_size';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| key_buffer_size | 134217728 |
+-----------------+-----------+
1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE 'key_read%';
+-------------------+------------+
| Variable_name | Value |
+-------------------+------------+
| Key_read_requests | 1407915295 |
| Key_reads | 713099 |
+-------------------+------------+
2 rows in set (0.00 sec)


Key_reads 代表命中磁盘的请求个数, Key_read_requests 是总数。命中磁盘的读请求数除以读请求总数就是不中比率 —— 在本例中每 2,000 个请求,大约有 1 个没有命中内存。如果每 1,000 个请求中命中磁盘的数目超过 1 个,就应该考虑增大关键字缓冲区了。例如,key_buffer = 128M 会将缓冲区设置为 128MB。

确定临时表的使用
临时表可以在更高级的查询中使用,其中数据在进一步进行处理(例如 GROUP BY 字句)之前,都必须先保存到临时表中;理想情况下,在内存中创建临时表。但是如果临时表变得太大,就需要写入磁盘中。

每次使用临时表都会增大 Created_tmp_tables;基于磁盘的表也会增大 Created_tmp_disk_tables。对于这个比率,并没有什么严格的规则,因为这依赖于所涉及的查询。长时间观察 Created_tmp_disk_tables 会显示所创建的磁盘表的比率,您可以确定设置的效率。

mysql> show variables like 'tmp_table_size';
+----------------+----------+
| Variable_name | Value |
+----------------+----------+
| tmp_table_size | 33554432 |
+----------------+----------+
1 row in set (0.00 sec)
mysql> show variables like 'max_heap_table_size';
+---------------------+----------+
| Variable_name | Value |
+---------------------+----------+
| max_heap_table_size | 16777216 |
+---------------------+----------+
1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE 'created_tmp%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Created_tmp_disk_tables | 92153 |
| Created_tmp_files | 48269 |
| Created_tmp_tables | 35837047 |
+-------------------------+----------+


每个会话的设置
注意这里针对的是每个会话的,它们在乘以可能存在的连接数的时候,这些选项表示大量的内存!

排序缓冲区(sort_buffer_size)
当 MySQL 必须要进行排序时,就会在从磁盘上读取数据时分配一个排序缓冲区来存放这些数据行。

如果要排序的数据太大,那么数据就必须保存到磁盘上的临时文件中,并再次进行排序。

mysql> show variables like 'sort_buffer_size';
+------------------+---------+
| Variable_name | Value |
+------------------+---------+
| sort_buffer_size | 2097144 |
+------------------+---------+
1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE 'sort%';
+-------------------+-----------+
| Variable_name | Value |
+-------------------+-----------+
| Sort_merge_passes | 31 |
| Sort_range | 99583552 |
| Sort_rows | 123728703 |
| Sort_scan | 64994 |
+-------------------+-----------+
4 rows in set (0.00 sec)


如果 sort_merge_passes 很大,就表示需要注意 sort_buffer_size。例如, sort_buffer_size = 2M 将排序缓冲区设置为 2MB。

读缓冲区(read_buffer_size)
理想情况下,索引提供了足够多的信息,可以只读入所需要的行。

但是有时候查询,需要读取表中大量数据。

要理解这种行为,需要知道运行了多少个 SELECT 语句Com_select ,以及需要读取表中的下一行数据的次数Handler_read_rnd_next。

mysql> SHOW STATUS LIKE "handler_read_rnd_next";
+-----------------------+-----------+
| Variable_name | Value |
+-----------------------+-----------+
| Handler_read_rnd_next | 788605837 |
+-----------------------+-----------+
1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE "com_select";
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| Com_select | 185910100 |
+---------------+-----------+
1 row in set (0.00 sec)
mysql>


Handler_read_rnd_next/Com_select =1/5 。如果该值超过4000,就应该查看read_buffer_size,虚拟系统为131072。

read_buffer_size

每个线程连续扫描时为扫描的每个表分配的缓冲区的大小(字节)。如果进行多次连续扫描,可能需要增加该值,默认值为131072。

<完>

玩LOFTER,免费冲印20张照片,人人有奖!     
我要抢>

this.p={ m:2,
b:2,
loftPermalink:'',
id:'fks_087069080087085064084087085095081086087067081080087067',


blogTitle:'mysql 的使用',

 blogAbstract:' ',
blogTag:'',
blogUrl:'blog/static/50605610200711815320752',
isPublished:1,
istop:false,
type:0,
modifyTime:1317332961985,
publishTime:1197093200752,
permalink:'blog/static/50605610200711815320752',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
vote:{},
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
mcon:'',
srk:-100,
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'',
selfRecomBlogCount:'0',
lofter_single:'<iframe width="140" height="560" style="overflow:hidden;" src="http://www.lofter.com/mailEntry.do?blogad=1&blog" frameBorder="0"></iframe>'
{list a as x}
{if !!x}
<div class="iblock nbw-fce nbw-f40">
<a class="fc03 noul" target="_blank" hidefocus="true" href="http://blog.163.com/${x.visitorName}/">
{if x.visitorName==visitor.userName}
<img alt="${x.visitorNickname|escape}" onerror="this.src=location.f40" class="cwd bdwa bdc0" src="${fn1(x.visitorName)}&r=${visitor.imageUpdateTime}"/>
{else}
<img alt="${x.visitorNickname|escape}" onerror="this.src=location.f40" class="cwd bdwa bdc0" src="${fn1(x.visitorName)}"/>
{/if}
</a>
<div class="cwd vname thide">
{if x.moveFrom=='wap'}


<a class="noul pnt" target="_blank" href="http://blog.163.com/services/wapblog.html?frompersonalbloghome"><span title="来自网易手机博客" class="iblock wapIcon"> </span></a>

 {elseif x.moveFrom=='iphone'}


<a class="noul pnt" target="_blank"><span title="来自iPhone客户端" class="iblock iphoneIcon"> </span></a>

 {elseif x.moveFrom=='android'}


<a class="noul pnt" target="_blank"><span title="来自Android客户端" class="iblock androidIcon"> </span></a>

 {elseif x.moveFrom=='mobile'}


<a class="noul pnt" target="_blank" href="http://blog.163.com/services/emsblog.html?frompersonalbloghome"><span title="来自网易短信写博" class="iblock wapIcon"> </span></a>

 {/if}
<a class="fc03 m2a" target="_blank" hidefocus="true" href="http://blog.163.com/${x.visitorName}/">
${fn(x.visitorNickname,8)|escape}
</a>
</div>
</div>
{/if}
{/list}
{if !!a}
<a target="_blank" href="http://blog.163.com/${a.userName}/"><img class="bdwa bdc0 pnt" onerror="this.src=location.f60" src="${fn1(a.userName)}"/></a>
<a target="_blank" class="fc03 m2a" href="http://blog.163.com/${a.userName}/">${fn(a.nickname,8)|escape}</a>
<div class="intro fc05">${a.selfIntro|escape}{if great260}${suplement}{/if}</div>
<div class="acts ztag"></div>
<div class="mbga phide xtag">
<div class="mbgai"> </div>
<a class="fc03 xtag m2a" href="#" target="_blank"></a>
</div>
{/if}
<#--最新日志,群博日志-->
{list a as x}
{if !!x}
<li class="thide"><a target="_blank" class="fc03 m2a" href="${furl()}${x.permalink}/?latestBlog">${fn(x.title,26)|escape}</a></li>
{/if}
{/list}
<#--推荐日志-->
<p class="fc06">推荐过这篇日志的人:</p>
<div>
{list a as x}
{if !!x}
<div class="iblock nbw-fce nbw-f40">
<a class="fc03 noul" target="_blank" hidefocus="true" href="http://blog.163.com/${x.recommenderName}/">
<img alt="${x.recommenderNickname|escape}" onerror="this.src=location.f40" class="cwd bdwa bdc0" src="${fn1(x.recommenderName)}"/>
</a>
<div class="cwd thide">
<a class="fc03 m2a" target="_blank" hidefocus="true" href="http://blog.163.com/${x.recommenderName}/">
${fn(x.recommenderNickname,6)|escape}
</a>
</div>
</div>
{/if}
{/list}
</div>
{if !!b&&b.length>0}
<p class="fc06">他们还推荐了:</p>
<ul>
{list b as y}
{if !!y}
<li class="rrb"><span class="iblock">·</span><a class="fc03 m2a" target="_blank" href="http://blog.163.com/${y.recommendBlogPermalink}/?from=blog/static/50605610200711815320752">${y.recommendBlogTitle|escape}</a></li>
{/if}
{/list}
</ul>
{/if}
<#--引用记录-->
<span class="pleft fc07">转载记录:</span>
<ul class="tbac">
{list d as x}
<li class="clearfix">
<span class="pleft iblock">·</span>
<div class="tbl thide pleft"><span><a target="_blank" class="fc07 m2a" href="${x.referBlogUrl}">${x.referBlogTitle|escape}</a></span></div>
<div class="tbr pleft"><span><a target="_blank" class="fc07 m2a" href="${x.referHomePage}">${x.referUserName|escape}</a></span></div>
</li>
{/list}
</ul>
<#--博主推荐-->
{list a as x}
{if !!x}
<li class="thide"><a target="_blank" class="fc03 m2a" href="http://blog.163.com/${x.userName}/${x.permalink}/?recommendBlog" title="${x.title|default:""|escape}">${x.title|default:""|escape}</a></li>
{/if}
{/list}
<#--随机阅读-->
{list a as x}
{if !!x}
<li class="thide"><a target="_blank" class="fc03 m2a" href="http://blog.163.com/${x.userName}/${x.permalink}/?personalRecomBlog" title="${x.title|default:""|escape}">${x.title|default:""|escape}</a></li>
{/if}
{/list}
<#--首页推荐-->
{list a as x}
{if !!x}
<li class="thide"><a target="_blank" class="fc03 m2a" target="_blank" href="${x.blogUrl|default:""|escape}?recommendReader" title="${x.blogTile|default:""|escape}">${x.blogTile|default:""|escape}</a></li>
{/if}
{/list}
<#--历史上的今天-->
<ul>
{list a as x}
{if x_index>4}{break}{/if}
{if !!x}
<li class="thide fc03">
<a class="m2a" target="_blank" href="http://blog.163.com/${x.userName}/${x.permalink|default:""}" title="${x.title|default:""|escape}">${fn1(x.title,60)|escape}</a><span class="fc07">${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}</span>
</li>
{/if}
{/list}
</ul>
<#--被推荐日志-->
{list a as x}
{if !!x}
<li class="thide"><a target="_blank" class="fc03 m2a" href="${furl()}${x.permalink}/">${fn(x.title,26)|escape}</a></li>
{/if}
{/list}
<#--上一篇,下一篇-->
{if !!(blogDetail.preBlogPermalink)}
<span class="ilft iblock icn0 icn0-620"> </span>
<div class="pleft thide"><a class="m2a" href="http://blog.163.com/circle_man/${blogDetail.preBlogPermalink}/">${blogDetail.preBlogTitle|escape}</a></div>
{/if}
{if !!(blogDetail.nextBlogPermalink)}
<span class="irgt iblock icn0 icn0-619"> </span>
<div class="pright thide"><a class="m2a" href="http://blog.163.com/circle_man/${blogDetail.nextBlogPermalink}/">${blogDetail.nextBlogTitle|escape}</a></div>
{/if}
<#-- 热度 -->
{list a as x}
{if !!x}
<div class="hotItem iblock nbw-fce nbw-f40">
<a class="fc03 noul" target="_blank" hidefocus="true" href="http://blog.163.com/${x.publisherUsername}/">
{if x.publisherUsername==visitor.userName}
<img alt="${x.publisherNickname|escape}" onerror="this.src=location.f40" class="cwd bdwa bdc0" src="${fn1(x.publisherUsername)}&r=${visitor.imageUpdateTime}"/>
{else}
<img alt="${x.publisherNickname|escape}" onerror="this.src=location.f40" class="cwd bdwa bdc0" src="${fn1(x.publisherUsername)}"/>
{/if}
</a>
<div class="cwd vname thide">
<a class="fc03 m2a" target="_blank" hidefocus="true" href="http://blog.163.com/${x.publisherUsername}/">
${fn(x.publisherNickname,8)|escape}
</a>
</div>
<a class="f-myLikeIcons hottype {if x.type==1} js-liketype{elseif x.type==2} js-reblogtype{elseif x.type==3} js-sharetype{else}{/if}" target="_blank" hidefocus="true" href="http://blog.163.com/${x.publisherUsername}/"> </a>
</div>
{/if}
{/list}
<#-- 网易新闻广告 -->
<div class="ttlbar fc06 bdwb bdc0 bds0">网易新闻</div>
<div class="newscnt">
<a class="headnews" hidefocus="true" target="_blank" href="${headlines.url_3w|escape}">
<img src="${imgsize(headlines.imgsrc,240,150,true)}">
<span class="icover"></span>
<span class="info"><span class="imgdesc thide">${headlines.title|escape}</span></span>
</a>
<ul>
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
<li class="thide"><a hidefocus="true" target="_blank" href="${x.url_3w|escape}" class="fc05"><span class="iblock dot">·</span>${x.title|escape}</a></li>
{/list}
{/if}
</ul>
<div class="download163news">


<a class="fc03" target="_blank" hidefocus="true" href="http://www.163.com/newsapp/">下载网易新闻客户端 ></a>

 </div>
</div>
<#--右边模块结构-->
<div class="uinfo ztag"></div>
<h4 class="fc07 fs0 ltt phide ztag">被推荐日志</h4>
<ul class="ztag blst"></ul>
<h4 class="fc07 fs0 ltt phide ztag">最新日志</h4>
<ul class="ztag blst"></ul>
<h4 class="fc07 fs0 ltt phide ztag">该作者的其他文章</h4>
<ul class="ztag blst"></ul>
<h4 class="fc07 fs0 ltt phide ztag">博主推荐</h4>
<ul class="ztag blst"></ul>
<h4 class="fc07 fs0 ltt phide ztag">随机阅读</h4>
<ul class="ztag blst"></ul>
<h4 class="fc07 fs0 ltt phide ztag">首页推荐</h4>
<ul class="ztag blst"></ul>


<div class="more"><a target="_blank" class="fc03 m2a" href="http://blog.163.com">更多>></a></div>

 <br/><br/>
<div id="yodaoad_r" style="display:none;_zoom:1;"></div>
<div id="lofter_single"></div>
<div id="blogPublicAccount"></div>
<#--评论模块结构-->
<div class="publish ztag"></div>
<div class="bdwt bds2 bdc0 phide" id="yodaoad_2" style="_zoom:1;"></div>
<div class="ztag bdwt bds2 bdc0">
<div class="case"></div>
<div class="clearfix"></div>
</div>
<#--引用模块结构-->
<div class="close">
<span class="ztag iblock icn0 icn0-57"> </span>
</div>
<div class="ztag phide"></div>
<#--博主发起的投票-->
{list a as x}
{if !!x}
<li>


<a href="http://blog.163.com/${x.userName}/" target="_blank" class="m2a fc03">${x.nickName|escape}</a>  投票给

 {var first_option = true;}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if} “${b[voteToOption_index]}”
{/if}
{/list}


{if (x.role!="-1") },“我是${c[x.role]}”  {/if}

 <span class="fc07"> ${fn1(x.voteTime)}</span>
{if x.userName==''}{/if}
{/if}
{/list}


<a rel="nofollow" class="pr" target="_blank" href="http://help.163.com/special/007525FT/blog.html?b13aze1">帮助</a>

 <span class="fr iblock space icn1 icn1-4"> </span>
<a class="pr" target="_blank" href="http://blog.163.com/activation.do?host=activation&&username=${u}">${u}</a>
{list wl as x}
<div class="grp">${x.g}</div>
{list x.l as y}
<a class="itm noul" href="#" hidefocus="true" name="{if typeof(y.v)=='string'}${y.v}{else}${y_index}{/if}">${y.n}</a>
{/list}
{/list}
{if defined('wl')}
{list wl as x}<a class="itm noul" href="#" hidefocus="true" name="${x.v}">${x.n}</a>{/list}
{/if}




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论