show master/slave status求根溯源
show master/slave status分别是查看主数据库以及副数据库的状态,是一种能查看主从复制运行情况的方式。
这里仅仅讨论linux下的nysql5.7.13版本的执行情况
一、show master status
开始与show global status类似,都是分配一个线程去处理该连接的命令(图1)
图1 show master status命令处理流程
1.在sql_yacc.cc:yyparse中
、
(1)初始化内存
(2)初始化解析后命令选项 SQLCOM_SHOW_MASTER_STAT
(3)初始化为单查询(此处无用)
2.show master status命令处理流程
图2. show_master_status的处理流程
(1)在mysql_execute_command(图2#3)中
进入该选项分支
case SQLCOM_SHOW_MASTER_STAT:
{
/* Accept one of two privileges */
if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
goto error;
res = show_master_status(thd);
break;
}
(2)在show_master_status(图2#2)中
1)初始化发送格式格式
field_list.push_back(new Item_empty_string("File", FN_REFLEN));
field_list.push_back(new Item_return_int("Position",,
MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Binlog_Do_DB",));
field_list.push_back(new Item_empty_string("Binlog_Ignore_DB",));
field_list.push_back(new Item_empty_string("Executed_Gtid_Set",
gtid_set_size)); if (thd->send_result_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2)储存内容并发送
protocol->start_row(); if (mysql_bin_log.is_open())
{
LOG_INFO li;
mysql_bin_log.get_current_log(&li);
size_t dir_len = dirname_length(li.log_file_name);
protocol->store(li.log_file_name + dir_len, &my_charset_bin);
protocol->store((ulonglong) li.pos);
store(protocol, binlog_filter->get_do_db());
store(protocol, binlog_filter->get_ignore_db());
protocol->store(gtid_set_buffer, &my_charset_bin);
if (protocol->end_row())
{
my_free(gtid_set_buffer);
DBUG_RETURN(true);
}
}
(3)在raw_get_current_log(图2#1)中
int MYSQL_BIN_LOG::get_current_log(LOG_INFO* linfo, bool need_lock_log/*true*/)
{
if (need_lock_log)
mysql_mutex_lock(&LOCK_log);
int ret = raw_get_current_log(linfo);
if (need_lock_log)
mysql_mutex_unlock(&LOCK_log);
return ret;
}
主要的处理函数就是raw_get_current_log
(4)在raw_get_current_log(图2#0)中
在binlog的那点事中的写位置定位有详细解释,这里不再赘述。
二、show slave status
图3 show slave status命令处理流程
1.在sql_yacc.cc:yyparse中
1)初始化信息
2)初始化信道
3)初始化执行命令类型
4)使用单查询(此处无用)
2.命令执行流程
图4 show slave status命令处理
(1)同样地在mysql_execute_command(图4#3)中
case SQLCOM_SHOW_MASTER_STAT:
{
/* Accept one of two privileges */
if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
goto error;
res = show_master_status(thd);
break;
}
(2)在show_master_status(图4#2)中
由于在解析中看到lex->mi.for_channel=false,为此进入此分支
if (!lex->mi.for_channel)
res= show_slave_status(thd);
(3)在show_master_status(图4#3)中
1)清空每一信道的内存
for (mi_map::iterator it= channel_map.begin(); it!=channel_map.end(); it++)
{
mi= it->second;
/*
The following statement is needed because, when mi->host[0]=0
we don't alloc memory for retried_gtid_set. However, we try
to free it at the end, causing a crash. To be on safeside,
we initialize it to NULL, so that my_free() takes care of it.
*/
io_gtid_set_buffer_array[idx]= NULL; if (mi != NULL && mi->host[])
{
const Gtid_set* io_gtid_set= mi->rli->get_gtid_set(); /*
@todo: a single memory allocation improves speed,
instead of doing it for each loop
*/ if ((io_gtid_set_size=
io_gtid_set->to_string(&io_gtid_set_buffer_array[idx])) < )
{
my_eof(thd);
my_free(sql_gtid_set_buffer); for (uint i= ; i < idx -; i++)
{
my_free(io_gtid_set_buffer_array[i]);
}
my_free(io_gtid_set_buffer_array); global_sid_lock->unlock();
DBUG_RETURN(true);
}
else
max_io_gtid_set_size= max_io_gtid_set_size > io_gtid_set_size ?
max_io_gtid_set_size : io_gtid_set_size;
}
idx++;
}
2)在show_slave_status_metadata,申请内存
void show_slave_status_metadata(List<Item> &field_list,
int io_gtid_set_size, int sql_gtid_set_size)
{ field_list.push_back(new Item_empty_string("Slave_IO_State", ));
field_list.push_back(new Item_empty_string("Master_Host",
HOSTNAME_LENGTH+));
field_list.push_back(new Item_empty_string("Master_User",
USERNAME_LENGTH+));
field_list.push_back(new Item_return_int("Master_Port", ,MYSQL_TYPE_LONG));
field_list.push_back(new Item_return_int("Connect_Retry", ,
MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Master_Log_File", FN_REFLEN));
field_list.push_back(new Item_return_int("Read_Master_Log_Pos", ,
MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Relay_Log_File", FN_REFLEN));
field_list.push_back(new Item_return_int("Relay_Log_Pos", ,
MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Relay_Master_Log_File",
FN_REFLEN));
field_list.push_back(new Item_empty_string("Slave_IO_Running", ));
field_list.push_back(new Item_empty_string("Slave_SQL_Running", ));
field_list.push_back(new Item_empty_string("Replicate_Do_DB", ));
field_list.push_back(new Item_empty_string("Replicate_Ignore_DB", ));
field_list.push_back(new Item_empty_string("Replicate_Do_Table", ));
field_list.push_back(new Item_empty_string("Replicate_Ignore_Table", ));
field_list.push_back(new Item_empty_string("Replicate_Wild_Do_Table", ));
field_list.push_back(new Item_empty_string("Replicate_Wild_Ignore_Table",
));
field_list.push_back(new Item_return_int("Last_Errno", , MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Last_Error", ));
field_list.push_back(new Item_return_int("Skip_Counter", ,
MYSQL_TYPE_LONG));
field_list.push_back(new Item_return_int("Exec_Master_Log_Pos", ,
MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_return_int("Relay_Log_Space", ,
MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Until_Condition", ));
field_list.push_back(new Item_empty_string("Until_Log_File", FN_REFLEN));
field_list.push_back(new Item_return_int("Until_Log_Pos", ,
MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Master_SSL_Allowed", ));
field_list.push_back(new Item_empty_string("Master_SSL_CA_File", FN_REFLEN));
field_list.push_back(new Item_empty_string("Master_SSL_CA_Path", FN_REFLEN));
field_list.push_back(new Item_empty_string("Master_SSL_Cert", FN_REFLEN));
field_list.push_back(new Item_empty_string("Master_SSL_Cipher", FN_REFLEN));
field_list.push_back(new Item_empty_string("Master_SSL_Key", FN_REFLEN));
field_list.push_back(new Item_return_int("Seconds_Behind_Master", ,
MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Master_SSL_Verify_Server_Cert",
));
field_list.push_back(new Item_return_int("Last_IO_Errno", , MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Last_IO_Error", ));
field_list.push_back(new Item_return_int("Last_SQL_Errno", , MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Last_SQL_Error", ));
field_list.push_back(new Item_empty_string("Replicate_Ignore_Server_Ids",
FN_REFLEN));
field_list.push_back(new Item_return_int("Master_Server_Id", sizeof(ulong),
MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Master_UUID", UUID_LENGTH));
field_list.push_back(new Item_empty_string("Master_Info_File",
* FN_REFLEN));
field_list.push_back(new Item_return_int("SQL_Delay", , MYSQL_TYPE_LONG));
field_list.push_back(new Item_return_int("SQL_Remaining_Delay", , MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Slave_SQL_Running_State", ));
field_list.push_back(new Item_return_int("Master_Retry_Count", ,
MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_empty_string("Master_Bind", HOSTNAME_LENGTH+));
field_list.push_back(new Item_empty_string("Last_IO_Error_Timestamp", ));
field_list.push_back(new Item_empty_string("Last_SQL_Error_Timestamp", ));
field_list.push_back(new Item_empty_string("Master_SSL_Crl", FN_REFLEN));
field_list.push_back(new Item_empty_string("Master_SSL_Crlpath", FN_REFLEN));
field_list.push_back(new Item_empty_string("Retrieved_Gtid_Set",
io_gtid_set_size));
field_list.push_back(new Item_empty_string("Executed_Gtid_Set",
sql_gtid_set_size));
field_list.push_back(new Item_return_int("Auto_Position", sizeof(ulong),
MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Replicate_Rewrite_DB", ));
field_list.push_back(new Item_empty_string("Channel_Name", CHANNEL_NAME_LENGTH));
field_list.push_back(new Item_empty_string("Master_TLS_Version", FN_REFLEN)); }
3)初始化发送协议
if (thd->send_result_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
{
goto err;
}
4)向各个信道发送要查询的状态
idx=;
for (mi_map::iterator it= channel_map.begin(); it!=channel_map.end(); it++)
{
mi= it->second; if (mi != NULL && mi->host[])
{
if (show_slave_status_send_data(thd, mi, io_gtid_set_buffer_array[idx],
sql_gtid_set_buffer))
goto err; if (protocol->end_row())
goto err;
}
idx++;
}
对于show_slave_status_send_data
bool show_slave_status_send_data(THD *thd, Master_info *mi,
char* io_gtid_set_buffer,
char* sql_gtid_set_buffer)
{
DBUG_ENTER("show_slave_status_send_data"); Protocol *protocol = thd->get_protocol();
char* slave_sql_running_state= NULL; DBUG_PRINT("info",("host is set: '%s'", mi->host)); protocol->start_row(); /*
slave_running can be accessed without run_lock but not other
non-volatile members like mi->info_thd or rli->info_thd, for
them either info_thd_lock or run_lock hold is required.
*/
mysql_mutex_lock(&mi->info_thd_lock);
protocol->store(mi->info_thd ? mi->info_thd->get_proc_info() : "",
&my_charset_bin);
mysql_mutex_unlock(&mi->info_thd_lock); mysql_mutex_lock(&mi->rli->info_thd_lock);
slave_sql_running_state= const_cast<char *>(mi->rli->info_thd ? mi->rli->info_thd->get_proc_info() : "");
mysql_mutex_unlock(&mi->rli->info_thd_lock); mysql_mutex_lock(&mi->data_lock);
mysql_mutex_lock(&mi->rli->data_lock);
mysql_mutex_lock(&mi->err_lock);
mysql_mutex_lock(&mi->rli->err_lock); DEBUG_SYNC(thd, "wait_after_lock_active_mi_and_rli_data_lock_is_acquired");
protocol->store(mi->host, &my_charset_bin);
protocol->store(mi->get_user(), &my_charset_bin);
protocol->store((uint32) mi->port);
protocol->store((uint32) mi->connect_retry);
protocol->store(mi->get_master_log_name(), &my_charset_bin);
protocol->store((ulonglong) mi->get_master_log_pos());
protocol->store(mi->rli->get_group_relay_log_name() +
dirname_length(mi->rli->get_group_relay_log_name()),
&my_charset_bin);
protocol->store((ulonglong) mi->rli->get_group_relay_log_pos());
protocol->store(mi->rli->get_group_master_log_name(), &my_charset_bin);
protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
"Yes" : (mi->slave_running == MYSQL_SLAVE_RUN_NOT_CONNECT ?
"Connecting" : "No"), &my_charset_bin);
protocol->store(mi->rli->slave_running ? "Yes":"No", &my_charset_bin);
store(protocol, rpl_filter->get_do_db());
store(protocol, rpl_filter->get_ignore_db()); char buf[];
String tmp(buf, sizeof(buf), &my_charset_bin);
rpl_filter->get_do_table(&tmp);
protocol->store(&tmp);
rpl_filter->get_ignore_table(&tmp);
protocol->store(&tmp);
rpl_filter->get_wild_do_table(&tmp);
protocol->store(&tmp);
rpl_filter->get_wild_ignore_table(&tmp);
protocol->store(&tmp); protocol->store(mi->rli->last_error().number);
protocol->store(mi->rli->last_error().message, &my_charset_bin);
protocol->store((uint32) mi->rli->slave_skip_counter);
protocol->store((ulonglong) mi->rli->get_group_master_log_pos());
protocol->store((ulonglong) mi->rli->log_space_total); const char *until_type= ""; switch (mi->rli->until_condition)
{
case Relay_log_info::UNTIL_NONE:
until_type= "None";
break;
case Relay_log_info::UNTIL_MASTER_POS:
until_type= "Master";
break;
case Relay_log_info::UNTIL_RELAY_POS:
until_type= "Relay";
break;
case Relay_log_info::UNTIL_SQL_BEFORE_GTIDS:
until_type= "SQL_BEFORE_GTIDS";
break;
case Relay_log_info::UNTIL_SQL_AFTER_GTIDS:
until_type= "SQL_AFTER_GTIDS";
break;
case Relay_log_info::UNTIL_SQL_VIEW_ID:
until_type= "SQL_VIEW_ID";
break;
case Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS:
until_type= "SQL_AFTER_MTS_GAPS";
case Relay_log_info::UNTIL_DONE:
until_type= "DONE";
break;
default:
DBUG_ASSERT();
}
protocol->store(until_type, &my_charset_bin);
protocol->store(mi->rli->until_log_name, &my_charset_bin);
protocol->store((ulonglong) mi->rli->until_log_pos); #ifdef HAVE_OPENSSL
protocol->store(mi->ssl? "Yes":"No", &my_charset_bin);
#else
protocol->store(mi->ssl? "Ignored":"No", &my_charset_bin);
#endif
protocol->store(mi->ssl_ca, &my_charset_bin);
protocol->store(mi->ssl_capath, &my_charset_bin);
protocol->store(mi->ssl_cert, &my_charset_bin);
protocol->store(mi->ssl_cipher, &my_charset_bin);
protocol->store(mi->ssl_key, &my_charset_bin); /*
The pseudo code to compute Seconds_Behind_Master:
if (SQL thread is running)
{
if (SQL thread processed all the available relay log)
{
if (IO thread is running)
print 0;
else
print NULL;
}
else
compute Seconds_Behind_Master;
}
else
print NULL;
*/ if (mi->rli->slave_running)
{
/*
Check if SQL thread is at the end of relay log
Checking should be done using two conditions
condition1: compare the log positions and
condition2: compare the file names (to handle rotation case)
*/
if ((mi->get_master_log_pos() == mi->rli->get_group_master_log_pos()) &&
(!strcmp(mi->get_master_log_name(), mi->rli->get_group_master_log_name())))
{
if (mi->slave_running == MYSQL_SLAVE_RUN_CONNECT)
protocol->store(0LL);
else
protocol->store_null();
}
else
{
long time_diff= ((long)(time() - mi->rli->last_master_timestamp)
- mi->clock_diff_with_master);
/*
Apparently on some systems time_diff can be <0. Here are possible
reasons related to MySQL:
- the master is itself a slave of another master whose time is ahead.
- somebody used an explicit SET TIMESTAMP on the master.
Possible reason related to granularity-to-second of time functions
(nothing to do with MySQL), which can explain a value of -1:
assume the master's and slave's time are perfectly synchronized, and
that at slave's connection time, when the master's timestamp is read,
it is at the very end of second 1, and (a very short time later) when
the slave's timestamp is read it is at the very beginning of second
2. Then the recorded value for master is 1 and the recorded value for
slave is 2. At SHOW SLAVE STATUS time, assume that the difference
between timestamp of slave and rli->last_master_timestamp is 0
(i.e. they are in the same second), then we get 0-(2-1)=-1 as a result.
This confuses users, so we don't go below 0: hence the max(). last_master_timestamp == 0 (an "impossible" timestamp 1970) is a
special marker to say "consider we have caught up".
*/
protocol->store((longlong)(mi->rli->last_master_timestamp ?
max(0L, time_diff) : ));
}
}
else
{
protocol->store_null();
}
protocol->store(mi->ssl_verify_server_cert? "Yes":"No", &my_charset_bin); // Last_IO_Errno
protocol->store(mi->last_error().number);
// Last_IO_Error
protocol->store(mi->last_error().message, &my_charset_bin);
// Last_SQL_Errno
protocol->store(mi->rli->last_error().number);
// Last_SQL_Error
protocol->store(mi->rli->last_error().message, &my_charset_bin);
// Replicate_Ignore_Server_Ids
{
char buff[FN_REFLEN];
ulong i, cur_len;
for (i= , buff[]= , cur_len= ;
i < mi->ignore_server_ids->dynamic_ids.size(); i++)
{
ulong s_id, slen;
char sbuff[FN_REFLEN];
s_id= mi->ignore_server_ids->dynamic_ids[i];
slen= sprintf(sbuff, (i == ? "%lu" : ", %lu"), s_id);
if (cur_len + slen + > FN_REFLEN)
{
/*
break the loop whenever remained space could not fit
ellipses on the next cycle
*/
sprintf(buff + cur_len, "...");
break;
}
cur_len += sprintf(buff + cur_len, "%s", sbuff);
}
protocol->store(buff, &my_charset_bin);
}
// Master_Server_id
protocol->store((uint32) mi->master_id);
protocol->store(mi->master_uuid, &my_charset_bin);
// Master_Info_File
protocol->store(mi->get_description_info(), &my_charset_bin);
// SQL_Delay
protocol->store((uint32) mi->rli->get_sql_delay());
// SQL_Remaining_Delay
if (slave_sql_running_state == stage_sql_thd_waiting_until_delay.m_name)
{
time_t t= my_time(), sql_delay_end= mi->rli->get_sql_delay_end();
protocol->store((uint32)(t < sql_delay_end ? sql_delay_end - t : ));
}
else
protocol->store_null();
// Slave_SQL_Running_State
protocol->store(slave_sql_running_state, &my_charset_bin);
// Master_Retry_Count
protocol->store((ulonglong) mi->retry_count);
// Master_Bind
protocol->store(mi->bind_addr, &my_charset_bin);
// Last_IO_Error_Timestamp
protocol->store(mi->last_error().timestamp, &my_charset_bin);
// Last_SQL_Error_Timestamp
protocol->store(mi->rli->last_error().timestamp, &my_charset_bin);
// Master_Ssl_Crl
protocol->store(mi->ssl_crl, &my_charset_bin);
// Master_Ssl_Crlpath
protocol->store(mi->ssl_crlpath, &my_charset_bin);
// Retrieved_Gtid_Set
protocol->store(io_gtid_set_buffer, &my_charset_bin);
// Executed_Gtid_Set
protocol->store(sql_gtid_set_buffer, &my_charset_bin);
// Auto_Position
protocol->store(mi->is_auto_position() ? : );
// Replicate_Rewrite_DB
rpl_filter->get_rewrite_db(&tmp);
protocol->store(&tmp);
// channel_name
protocol->store(mi->get_channel(), &my_charset_bin);
// Master_TLS_Version
protocol->store(mi->tls_version, &my_charset_bin); mysql_mutex_unlock(&mi->rli->err_lock);
mysql_mutex_unlock(&mi->err_lock);
mysql_mutex_unlock(&mi->rli->data_lock);
mysql_mutex_unlock(&mi->data_lock); DBUG_RETURN(false);
}
在这个函数和show_slave_status_metadata中,我们可以看到每个状态取自那个函数,这样就可以弄明白每个状态的实时更新性
在这里我们关注的是Master_Log_File和 Read_Master_Log_Pos的状态。这是主从同步情况最主要的状态,但是这涉及到slave IO的运行情况,我们下次在slave IO说明
show master/slave status求根溯源的更多相关文章
- Mysql命令show global status求根溯源
近来,发现好多公司对mysql的性能监控是通过show global status实现的,因此对于这个命令想要探究一番,看他是否是实时更新的. 在此之前,我们必须搞明白mysql对于这个命令的执行过程 ...
- MySQL show master / slave status 命令参数
一.show master status 二.show slave status Slave_IO_State SHOW PROCESSLIST输出的State字段的拷贝.SHOW PROCESSLI ...
- 两主机搭建MySQL主从复制后,show slave status显示:Last_IO_Error: error connecting to master ……
两台主机A.B搭建mysql主从复制关系(A为master,B为slave)后,在slave上执行show slave status,结果中显示Last_IO_Error: error connect ...
- [置顶] 两主机搭建MySQL主从复制后,show slave status显示:Last_IO_Error: error connecting to master ……
两台主机A.B搭建mysql主从复制关系(A为master,B为slave)后,在slave上执行show slave status,结果中显示Last_IO_Error: error connect ...
- show master status, show slave status中的Executed_Gtid_Set
slave 如果server是slave节点,在server上执行show master staus与show slave status显示的Executed_Gtid_Set是一样的. slave也 ...
- 在阿里云Centos7.6上面配置Mysql主从数据库(master/slave),实现读写分离
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_85 在之前的一篇文章中,阐述了如何在高并发高负载的场景下使用nginx做后台服务的负载均衡:在阿里云Centos上配置nginx+ ...
- Windows下搭建MySQL Master Slave
一.背景 服务器上放了很多MySQL数据库,为了安全,现在需要做Master/Slave方案,因为操作系统是Window的,所以没有办法使用keepalived这个HA工具,但是我们可以接受人工进行切 ...
- mysql (master/slave)复制原理及配置
1 复制概述 Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重 ...
- show slave status中的log_file / log_pos
在MySQL的master-slave或dual master的架构中,我们经常使用show slave status命令来查看复制状态. 这里涉及几个重要的日志文件和位置: Master_Log_F ...
随机推荐
- NAIPC-2016
A. Fancy Antiques 爆搜+剪枝. #include <bits/stdc++.h> using namespace std ; typedef pair < int ...
- Php:学习笔记(一):版本选择
(注:本文来自网络) 超过75%的网站使用了PHP作为开发语言,wordpress,phpmyadmin和其他一些开源项目的盛行,带来了一大批的长尾用户.然而,他们一般安装之后却很少升级.下图是目前P ...
- MVC框架
MVC (Modal View Controler)本来是存在于Desktop程序中的,M是指数据模型,V是指用户界面,C则是控制器.使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用 ...
- python中__init__问题
python中安装目录中的Lib文件夹模块中的__init__.py文件(文件内容可以为空),用于标识此文件夹是一个模块 python编程中的__init__表示初始化
- js判断undefined类型
js判断undefined类型 if (reValue== undefined){ alert("undefined"); } 发现判断不出来,最后查了下资料要用ty ...
- java记录
1. 包装类与自动装箱问题:在justjavac的博客上看到翻译的一篇文章 离开java,寻找更佳语言的十大理由 中关于自动装箱的一个描述: 这个特性是为了解决因原生类型的存在所导致的问题,在Java ...
- [LintCode] Intersection of Two Linked Lists 求两个链表的交点
Write a program to find the node at which the intersection of two singly linked lists begins. Notice ...
- 关于DOM的一些笔记(一)
这篇文章整理的是关于DOM的一些学习笔记,这样以后查找起来也方便许多.(以前js看的是入门经典和DOM编程艺术,现在在看高级程序设计,本文就以高级程序为主整理) 1.Node (1):类型 node. ...
- MySQL数据表range分区例子
某些行业数据量的增长速度极快,随着数据库中数据量的急速膨胀,数据库的插入和查询效率越来越低.此时,除了程序代码和查询语句外,还得在数据库的结构上做点更改:在一个主读辅写的数据库中,当数据表数据超过10 ...
- maven 本地仓库和远程仓库
在Maven中,任何一个依赖.插件或者项目构建的输出,都可以称之为构件. Maven在某个统一的位置存储所有项目的共享的构件,这个统一的位置,我们就称之为仓库.(仓库就是存放依赖和插件的地方) 任何的 ...