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求根溯源的更多相关文章

  1. Mysql命令show global status求根溯源

    近来,发现好多公司对mysql的性能监控是通过show global status实现的,因此对于这个命令想要探究一番,看他是否是实时更新的. 在此之前,我们必须搞明白mysql对于这个命令的执行过程 ...

  2. MySQL show master / slave status 命令参数

    一.show master status 二.show slave status Slave_IO_State SHOW PROCESSLIST输出的State字段的拷贝.SHOW PROCESSLI ...

  3. 两主机搭建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 ...

  4. [置顶] 两主机搭建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 ...

  5. show master status, show slave status中的Executed_Gtid_Set

    slave 如果server是slave节点,在server上执行show master staus与show slave status显示的Executed_Gtid_Set是一样的. slave也 ...

  6. 在阿里云Centos7.6上面配置Mysql主从数据库(master/slave),实现读写分离

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_85 在之前的一篇文章中,阐述了如何在高并发高负载的场景下使用nginx做后台服务的负载均衡:在阿里云Centos上配置nginx+ ...

  7. Windows下搭建MySQL Master Slave

    一.背景 服务器上放了很多MySQL数据库,为了安全,现在需要做Master/Slave方案,因为操作系统是Window的,所以没有办法使用keepalived这个HA工具,但是我们可以接受人工进行切 ...

  8. mysql (master/slave)复制原理及配置

    1 复制概述 Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重 ...

  9. show slave status中的log_file / log_pos

    在MySQL的master-slave或dual master的架构中,我们经常使用show slave status命令来查看复制状态. 这里涉及几个重要的日志文件和位置: Master_Log_F ...

随机推荐

  1. 1、Spring In Action 4th笔记(1)

    Spring In Action 4th笔记(1) 2016-12-28 1.Spring是一个框架,致力于减轻JEE的开发,它有4个特点: 1.1 基于POJO(Plain Ordinary Jav ...

  2. 配置linux服务器的一些操作

    本次课程实验,我们选择的是ubuntu 14.04操作系统,不像使用RDP连接windows服务器那样可以直观的看到远程端的图形界面,只能通过Xshell以命令行进行操作,那么就来说说配置远程linu ...

  3. log4j使用--http://www.cnblogs.com/eflylab/archive/2007/01/11/618001.html

    package log4jTest.com; import java.io.FileReader; import org.apache.log4j.BasicConfigurator; import ...

  4. 解决Xcode真机测试时ineligible devices的问题

    升级了Xcode到6.3,连接真机测试时,出现不能选择设备.如图: 设备系统版本是8.3的,Xcode连接其他低系统版本的设备做真机测试时就不会有这个问题. 有人说这是Xcode6.3的bug. 我的 ...

  5. 【转】《从入门到精通云服务器》第七讲—IAAS、PAAS、SAAS

    Saas.Paas.IaaS这三个词,一直困扰众人很久.就拿字面意思来说,分别是:软件即服务,平台即服务,设施即服务.小编表示这个不往深了讲,真心看不懂,还容易弄混淆.今天我们就来扒一扒这三者的深层含 ...

  6. bzoj 4327: JSOI2012 玄武密码

    听说这题不公开.. 那就不贴题意了 一眼看上去还以为是exkmp的裸题.. 看了数据范围,呵呵.. 多串匹配嘛.. 就用AC自动机咯,而且每个点最多也就只有$4$个孩子 用原串在AC自动机上走,碰到的 ...

  7. 三星首次更新Gear VR虚拟现实浏览器Samsung Internet

    通过VR浏览网页不是问题,不过你需要一个专门的VR浏览器,而GearVR的虚拟现实应用名为"Samsung Internet for Gear VR".继去年12月份上线后,迎来了 ...

  8. U-Boot Driver Model领域模型设计

    需求分析 在2014年以前,uboot没有一种类似于linux kernel的设备驱动模型,随着uboot支持的设备越来越多,其一直受到如下问题困扰: 设备初始化流程都独立实现,而且为了集成到系统,需 ...

  9. tornado 学习笔记15 _ServerRequestAdapter分析

         继承于HTTPMessageDeletegate,是HTTPMessageDeletegate的一种实现,用于处理请求消息. 15.1 构造函数 def __init__(self, ser ...

  10. MVC项目中ExecutionTimeout不生效的解决方案

    我们做web服务器端开发时,经常会遇到一个需求场景,因为某些耗时处理造成页面的响应处理时间超长,技术角度就想能否给页面处理程序一个指定的超时时间,服务端处理程序执行时间超过这个指定的超时时间则中断处理 ...