Mysql source code learning notes-peek thread bitsCN.com
After installing Mysql, use VS to open the source code. I just need to open it. how is the difference between this code and the imagination? I felt that the code was a little messy, and the comments and codes were written at random. there seemed to be no uniform specification, and there were also differences in the code styles in different files. Maybe Mysql had gone through a lot of cool hands, let's gather the talents. It may also be because I have a relatively simple understanding, adapted to my own code style, and finally started my source code journey with reverence. I am a Cainiao.
Mysql can be started. how can I learn it? You can't start from main. Mysql, as a relatively low-level large-scale software, involves all aspects of database implementation. it does not have a solid theoretical foundation of the database and is quite familiar with Mysql modules, starting from main, we are bound to introduce ourselves into a dead end. we can't afford to worry about anything.
After thinking, I want to debug the server through the client to learn the server code. That is to say, through the action of the client, we can see the response of the server. For example, from the client login action to see how the SERVER communicates, user identification, authentication, and task allocation, through create table, let's look at how the SERVER parses DDL statements and uses different physical storage methods for different storage engines, and use INSERT statements to see how the SERVER performs Btree operations. Through the SELECT statement, we can see how to create and optimize the SQL statement syntax tree. through the ROLL BACK, we can see how the SERVER transaction is implemented. Here, we mainly learn the idea of Mysql database implementation through tracking the code, and do not conduct too many investigations on the specific code (I am not very familiar with C ++). I am good at reading and not understanding it, haha.
As a result, the following SQL statements have been prepared for SERVER analysis.
1. LOGIN)
Mysql.exe-uroot-p
2. DDL (table creation statement)
Create table tb_myisam (c1 int, c2 varchar (256) engine = myisam;
Create table tb_innodb (c1 int, c2 varchar (256) engine = innodb;
3. INSERT
Insert into tb_myisam values (1, 'Lonely fat ');
Insert into tb_innodb values (1, 'Lonely fat ');
4. SELECT
Select c1 from tb_myisam;
Select * from tb_innodb;
5. ROLLBACK
As we all know, mysql can perform concurrent operations through multiple clients, including logon. When others log on, other users may be performing some other operations. Therefore, we guess there should be a dedicated thread responsible for creating connections between the client and the server, to ensure timely login, each connected user should use an independent thread for task execution.
First, we will introduce the thread creation function in mysql. the thread creation function seems to be _ begin_thread and CreateThread. we will search through VS in the entire solution, bingo! In my_winthread.c, I found the function pthread_create that calls _ begin_thread, and os0thread. c found the function OS _thread_create that calls CreateThread. how does one system encapsulate two system functions ?? Take a closer look and find that my_winthread.c is under the project mysys, while os0thread. c is under the project innobase. Innobase !! Isn't this the plug-in storage engine of innodb? it turns out to be the underlying function encapsulated by the storage engine. I think Mysql has a wide range of applications. apart from open source, plug-in storage engines are indispensable. Users can adopt different storage engines based on their actual applications. for large companies, it is estimated that you will develop your own storage engine.
Next we will analyze how pthread_create calls _ begin_thread. let's take a rough look at the source code.
Int pthread_create (pthread_t * thread_id, pthread_attr_t * attr,
Pthread_handler func, void * param)
{
HANDLE hThread;
Struct pthread_map * map;
DBUG_ENTER ("pthread_create ");
If (! (Map = malloc (sizeof (* map ))))
DBUG_RETURN (-1 );
Map-> func = func;
Map-> param = param;
Pthread_mutex_lock (& THR_LOCK_thread );
# Ifdef _ BORLANDC __
HThread = (HANDLE) _ beginthread (void (_ USERENTRY *) (void *) pthread_start,
Attr-> dwStackSize? Attr-> dwStackSize:
65535, (void *) map );
# Else
HThread = (HANDLE) _ beginthread (void (_ cdecl *) (void *) pthread_start,
Attr-> dwStackSize? Attr-> dwStackSize:
65535, (void *) map );
# Endif
DBUG_PRINT ("info", ("hThread = % lu", (long) hThread ));
* Thread_id = map-> pthreadself = hThread;
Pthread_mutex_unlock (& THR_LOCK_thread );
If (hThread = (HANDLE)-1)
{
Int error = errno;
DBUG_PRINT ("error ",
("Can't create thread to handle request (error % d)", error ));
DBUG_RETURN (error? Error:-1 );
}
VOID (SetThreadPriority (hThread, attr-> priority ));
DBUG_RETURN (0 );
}
The key code is as follows:
Map-> func = func;
Map-> param = param;
_ Beginthread (void (_ cdecl *) (void *) pthread_start,
Attr-> dwStackSize? Attr-> dwStackSize:
65535, (void *) map );
From this we can see that the name of the newly created thread is a fixed function-pthread_start, and the function func we want to create is mounted on the map, the parameters of the function are mounted to the map, so that we can infer that the pthread_start function will certainly show the code as follows:
Map-> func (map-> param );
Mysql does not choose the form of direct _ beginthread (func, stack_size, param), but implements an encapsulation. I don't know what the benefits are, maybe the idea of cool people is not something that Cainiao like me can understand. I just ran off my questions ~~
Now, we only set the breakpoint on the pthread_create function, debug and start mysqld, and stop the breakpoint to check the thread status of the system:
We entered pthread_create for the first time. no threads have been created yet. it is reasonable to say that the system thread should have only one main thread, but now there are so many more threads, these should be the threads created by the innodb storage engine (specifically in plugin_init ). Based on the thread name and comments, I guessed the role of these threads.
Io_handler_thread: from the name, we can know that these are I/O threads and are responsible for disk I/O.
Svr_error_monitor_thread: the monitoring thread for server errors.
Svr_lock_timeout_thread: the lock-related thread.
Svr_master_thread:
/*************************************** **********************************
The master thread controlling the server .*/
The server control thread should be the specific job thread.
Svr_monitor_thread:
/*************************************** **********************************
A thread prints the info output by various InnoDB monitors .*/
The monitoring thread is responsible for printing information.
Let's skip this step. we only care about the threads created by pthread_create. Based on debugging, several threads with the same name are added:
When debugging, you can view the stack to understand the creator and role of the three threads, as shown below:
Creator
Processing functions
Create_shutdown_thread
Handle_shutdown
Start_handle_manager
Handle_manager
Handle_connections_methods
Handle_connections_sockets
Creator: The function that calls pthread_create to create a thread.
Handler: Call the specific thread function of the thread created by pthread_create.
We can see from the name that handle_connections_sockets should be the thread that processes the connection. in order, it should also be like this. only after all other required threads in the system are created, to create a listening thread (connection thread), that is, the listening thread should be last created by the system.
Find the thread we need for LOGIN. next time, we will analyze how to log on to the thread and what resources will be allocated to the user after logon. It's not too early. it's time to wash and sleep.
From the innocent bitsCN.com