Database Thread Pool Control Method and Device, Electronic Device, Computer Medium
By loading dynamic runtime libraries in MySQL database to replace threads with coroutines, the performance problems caused by frequent creation/destruction of high concurrent threads and the problem of low priority task latency are solved, and more efficient concurrency performance and task response stability are achieved.
Patent Information
- Application Number
- CN202310942845.1
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2023-07-28
- Publication Date
- 2025-06-17
- Estimated Expiration
- 2043-07-28
AI Technical Summary
In high concurrency scenarios, frequent creation/destruction of MySQL databases leads to jamming or crashing, and the delay of low-priority tasks in thread pool mode is intensified, and even the "starved" phenomenon that tasks can never respond.
By loading a dynamic runtime library that can replace threads with coroutines in the database operating system, generate coroutine scheduling threads, receive client connection requests, detect and respond to database requests to create new threads, create coroutines corresponding to connection requests, and schedule coroutines through coroutine scheduling threads to complete access tasks.
It solves the problems of increased latency of low-priority tasks and jitter in task response speed, improves the concurrency performance of the database, and avoids the phenomenon of "starving death" of tasks.
Smart Images

Figure CN119166291B_ABST
Abstract
Description
Technical Field
[0001] The present disclosure relates to the field of computer technologies, and particularly to a method and apparatus for controlling a database thread pool, an electronic device, and a computer-readable medium. Background Art
[0002] The default concurrent connection model of the MySQL database adopts "one thread for one connection", that is, a thread is created for each connection. One major defect of this database is that in a high-concurrency scenario, frequently creating / destroying threads may cause the database to freeze or crash. In addition, even in the long-connection mode, a large number of threads will greatly increase the task scheduling burden.
[0003] To solve the above problems, some databases have introduced a thread pool solution. The purpose of the thread pool technology is to use a fixed number of threads to process tasks far exceeding the number of threads in the thread pool in a round-robin response manner, so as to reduce scheduling contention and resource occupancy. However, in this mode, if all tasks are at the same priority, then in the case where the task execution time is generally long, some urgently needed tasks will have a high delay. Therefore, some thread pools have introduced a high-priority queue. However, when there are many tasks in the high-priority queue or the execution time is generally long, the delay of low-priority tasks will be further aggravated. In extreme cases, there will be a phenomenon where some tasks will never get a response, and this phenomenon is called the "starvation" phenomenon. Summary of the Invention
[0004] Embodiments of the present disclosure provide a method and apparatus for controlling a database thread pool, an electronic device, and a computer-readable medium.
[0005] In a first aspect, an embodiment of the present disclosure provides a method for controlling a database thread pool. The method includes: loading a dynamic runtime library capable of replacing threads with coroutines in the operating system of the database to generate at least one coroutine scheduling thread for scheduling at least one coroutine; receiving a connection request sent by a client to the database; detecting whether a request for the database to create a new thread is a request for processing the connection request; in response to detecting that the request for the database to create a new thread is a request for processing the connection request, creating a coroutine corresponding to the connection request, and scheduling the coroutine through at least one coroutine scheduling thread to complete an access task corresponding to the connection request.
[0006] In some embodiments, loading a dynamic runtime library capable of replacing threads with coroutines in the operating system of the database to generate at least one coroutine scheduling thread includes: in response to the database being unable to modify the source code and not having a connection management plug-in mechanism, starting the database; loading and initializing the dynamic runtime library to generate at least one coroutine scheduling thread, where the dynamic runtime library has a hook function for creating threads, and the hook function for creating threads is used to replace the connection processing thread generated by the native runtime library of the database with a coroutine; when initializing the database, overloading the hook function for creating threads to determine whether the currently created thread is a connection processing thread through the hook function for creating threads, and when the currently created thread is a connection processing thread, converting the connection processing thread into a coroutine.
[0007] In some embodiments, loading a dynamic runtime library capable of replacing threads with coroutines in the operating system of the database to generate at least one coroutine scheduling thread includes: in response to the database having a connection management plug-in mechanism, starting the database; loading and initializing the dynamic runtime library to generate at least one coroutine scheduling thread; initializing the database; loading and initializing the plug-in so that when the plug-in receives a connection request sent to the database and the thread construction request of the database is a request for processing the connection request, controlling the hook function for creating threads in the dynamic runtime library to work, where the hook function for creating threads is used to determine whether the currently created thread is a connection processing thread, and when the currently created thread is a connection processing thread, converting the connection processing thread into a coroutine.
[0008] In some embodiments, the above method further includes: dividing at least one coroutine scheduling thread into an I / O intensive scheduling thread and a compute intensive scheduling thread; the above scheduling the coroutine to complete the access task corresponding to the connection request through at least one coroutine scheduling thread includes: detecting whether the coroutine corresponding to the connection request is in a state between a first state and a second state, where the first state is the state of the coroutine waiting to execute a database command packet, the packet has arrived, and the coroutine needs to be awakened; the second state is the state of the coroutine located in the compute intensive scheduling thread and the coroutine initiating a specific write request to a specific file; if it is detected that the coroutine corresponding to the connection request is in a state between the first state and the second state, scheduling the coroutine corresponding to the connection request using the compute intensive scheduling thread in at least one coroutine scheduling thread; if it is detected that the coroutine corresponding to the connection request is not in a state between the first state and the second state, scheduling the coroutine corresponding to the connection request using the I / O intensive scheduling thread in at least one coroutine scheduling thread.
[0009] In some embodiments, when it is detected that the coroutine corresponding to the connection request is not in a state between the first state and the second state, scheduling the coroutine corresponding to the connection request by using an I / O intensive scheduling thread among at least one coroutine scheduling thread includes: in response to the coroutine corresponding to the connection request being in the stage of creating a connection, placing the coroutine in the current I / O intensive scheduling thread, where the current I / O intensive scheduling thread is determined based on a load balancing algorithm; in response to the coroutine corresponding to the connection request being in a specific write operation on a specific file, and before the submission of the I / O request for writing the specific file is completed and the coroutine yields and enters I / O waiting, migrating the coroutine to the current I / O intensive scheduling thread.
[0010] In some embodiments, the above database is a MySQL database. When the coroutine corresponding to the connection request is in a specific write operation on a specific file, and before the submission of the I / O request for writing the specific file is completed and the coroutine yields and enters I / O waiting, migrating the coroutine to the current I / O intensive scheduling thread includes: in response to the coroutine corresponding to the connection request being in a write operation on a binary log file, and before the submission of the I / O request for writing the file is completed and the coroutine yields and enters I / O waiting, migrating the coroutine to the current I / O intensive scheduling thread.
[0011] In some embodiments, the above method further includes: detecting whether there is a coroutine in the I / O intensive scheduling thread that drives batch submission; if there is a coroutine in the I / O intensive scheduling thread that drives batch submission, migrating the coroutine woken up by the coroutine that drives batch submission to the I / O intensive scheduling thread, where the I / O intensive scheduling thread into which the coroutine woken up by the coroutine that drives batch submission migrates is determined based on a load balancing algorithm.
[0012] In some embodiments, the above database is a MySQL database with group commit enabled. Detecting whether there is a coroutine in the I / O intensive scheduling thread that drives batch submission includes: detecting whether there is a group leader coroutine in the I / O intensive scheduling thread that drives the group commit process for writing the binary log file; if there is a coroutine in the I / O intensive scheduling thread that drives batch submission, migrating the coroutine woken up by the coroutine to the I / O intensive scheduling thread includes: if it is detected that there is a group leader coroutine for writing the binary log file, migrating the member coroutines woken up by the group leader coroutine to the I / O intensive scheduling thread, where the I / O intensive scheduling thread into which each member coroutine migrates is determined based on a load balancing algorithm.
[0013] Second aspect, embodiments of the present disclosure provide a database thread pool control device, the device includes: a loading unit configured to load in the operating system of the database a dynamic runtime library capable of replacing threads with coroutines, and generate at least one coroutine scheduling thread for scheduling at least one coroutine; a receiving unit configured to receive a connection request sent by a client to the database; a detecting unit configured to detect whether a request for the database to create a new thread is a request for processing the connection request; a creating unit configured to, in response to detecting that the request for the database to create a new thread is a request for processing the connection request, create a coroutine corresponding to the connection request, and schedule the coroutine through at least one coroutine scheduling thread to complete the access task corresponding to the connection request.
[0014] In some embodiments, the above-mentioned loading unit is configured to: when the database cannot modify the source code and does not have a connection management plug-in mechanism, start the database; load and initialize the dynamic runtime library, and generate at least one coroutine scheduling thread. The dynamic runtime library has a hook function for creating a thread, and the hook function for creating a thread is used to replace the connection processing thread generated by the native runtime library of the database with a coroutine; when the database is initialized, reload the hook function for creating a thread to determine whether the currently created thread is a connection processing thread through the hook function for creating a thread, and when the currently created thread is a connection processing thread, convert the connection processing thread into a coroutine.
[0015] In some embodiments, the above-mentioned loading unit is configured to: when the database has a connection management plug-in mechanism, start the database; load and initialize the dynamic runtime library, and generate at least one coroutine scheduling thread; initialize the database; load and initialize the plug-in so that the plug-in receives the connection request sent to the database, and when the thread construction request of the database is a request for processing the connection request, control the hook function for creating a thread in the dynamic runtime library to work. The hook function for creating a thread is used to determine whether the currently created thread is a connection processing thread, and when the currently created thread is a connection processing thread, convert the connection processing thread into a coroutine.
[0016] In some embodiments, the above-mentioned apparatus further includes: a partitioning unit configured to partition at least one coroutine scheduling thread into an I / O-intensive scheduling thread and a compute-intensive scheduling thread; the above-mentioned creation unit is further configured to: detect whether the coroutine corresponding to the connection request is in a state between a first state and a second state, where the first state is the state of the coroutine waiting to execute a database command packet, the packet has arrived, and the coroutine needs to be woken up; the second state is the state where the coroutine is located in the compute-intensive scheduling thread and the coroutine initiates a specific write request for a specific file; if it is detected that the coroutine corresponding to the connection request is in a state between the first state and the second state, schedule the coroutine corresponding to the connection request using the compute-intensive scheduling thread among at least one coroutine scheduling thread; if it is detected that the coroutine corresponding to the connection request is not in a state between the first state and the second state, schedule the coroutine corresponding to the connection request using the I / O-intensive scheduling thread among at least one coroutine scheduling thread.
[0017] In some embodiments, the above-mentioned creation unit is further configured to: in response to the coroutine corresponding to the connection request being in the stage of creating a connection, place the coroutine on the current I / O-intensive scheduling thread, and the current I / O-intensive scheduling thread is determined based on the load balancing algorithm; in response to the coroutine corresponding to the connection request being in a specific write operation on a specific file and before completing the submission of the I / O request for writing the specific file and yielding the coroutine to enter I / O waiting, migrate the coroutine to the current I / O-intensive scheduling thread.
[0018] In some embodiments, the above-mentioned database is a MySQL database, and the above-mentioned construction unit is further configured to: in response to the coroutine corresponding to the connection request being in a write operation on a binary log file and before completing the submission of the I / O request for writing the file and yielding the coroutine to enter I / O waiting, migrate the coroutine to the current I / O-intensive scheduling thread.
[0019] In some embodiments, the above-mentioned apparatus further includes: a batch driving unit, and the batch driving unit is configured to: detect whether there is a coroutine for driving batch submission in the I / O-intensive scheduling thread; if there is a coroutine for driving batch submission in the I / O-intensive scheduling thread, migrate the coroutine woken up by the coroutine for driving batch submission to the I / O-intensive scheduling thread, and the I / O-intensive scheduling thread into which the coroutine woken up by the coroutine for driving batch submission migrates is determined based on the load balancing algorithm.
[0020] In some embodiments, the above database is a MySQL database with group commit enabled, and the batch driving unit is further configured to: detect whether there is a leading coroutine in the IO-intensive scheduling thread that drives the group commit process for writing to the binary log file; if a group leader coroutine for writing to the binary log file is detected, migrate the member coroutines that wake up the group leader coroutine to the IO-intensive scheduling thread, and the IO-intensive scheduling threads into which each member coroutine migrates are determined based on the load balancing algorithm.
[0021] In a third aspect, an embodiment of the present disclosure provides an electronic device, which includes: one or more processors; a storage device on which one or more programs are stored; when the one or more programs are executed by the one or more processors, the one or more processors implement the method described in any one of the embodiments in the first aspect.
[0022] In a fourth aspect, an embodiment of the present disclosure provides a computer-readable medium, on which a computer program is stored, and when the program is executed by a processor, it implements the method described in any one of the embodiments in the first aspect.
[0023] For the database thread pool control method and device provided by the embodiments of the present disclosure, first, a dynamic runtime library capable of replacing threads with coroutines is loaded in the operating system of the database to generate at least one coroutine scheduling thread, and the coroutine scheduling thread is used to schedule at least one coroutine; second, a connection request sent by a client to the database is received; third, it is detected whether the request for the database to create a new thread is a request for processing the connection request; finally, in response to detecting that the request for the database to create a new thread is a request for processing the connection request, a coroutine corresponding to the connection request is created, and the coroutine is scheduled by at least one coroutine scheduling thread to complete the access task corresponding to the connection request. Thus, through the injection method of the dynamic runtime library, the connection processing threads used to process connections in the database are transparently replaced with coroutines, and the created coroutines corresponding to the connection requests run in a time-sharing call form. When time-consuming operations such as suspension and waiting occur in a certain coroutine, the current coroutine scheduling thread can be actively relinquished, and another executable coroutine can be swapped in by the coroutine scheduling thread, which can solve the problems of increased delay of low-priority tasks and jitter in task response speed, and improve the concurrency performance of the database. BRIEF DESCRIPTION OF THE DRAWINGS
[0024] By reading the detailed description of the non-limiting embodiments with reference to the following drawings, other features, objectives, and advantages of the present disclosure will become more apparent:
[0025] Figure 1 is a flowchart of an embodiment of the database thread pool control method according to the present disclosure;
[0026] Figure 2It is a schematic diagram of a database structure disclosed in the present invention;
[0027] Figure 3 is a flowchart of another embodiment of a database thread pool control method according to the present disclosure;
[0028] Figure 4 is a structural schematic diagram of an embodiment of a database thread pool control device according to the present disclosure;
[0029] Figure 5 It is a schematic diagram of the structure of an electronic device suitable for implementing the embodiments of the present disclosure. DETAILED DESCRIPTION
[0030] The present disclosure is further described in detail below in conjunction with the accompanying drawings and embodiments. It is understood that the specific embodiments described herein are only used to explain the relevant invention, rather than to limit the invention. It is also necessary to explain that, for ease of description, only the parts related to the relevant invention are shown in the accompanying drawings.
[0031] It should be noted that, in the absence of conflict, the embodiments and features in the embodiments of the present disclosure may be combined with each other. The present disclosure will be described in detail below with reference to the accompanying drawings and in combination with the embodiments.
[0032] In traditional database technology, Percona has introduced a thread pool solution, which effectively controls the number of threads and reduces thread switching by executing SQL (Structured Query Language) instructions in different connections in the thread pool in a time-sharing manner, thereby ensuring system performance and stability to a certain extent.
[0033] When the thread pool is enabled, client connections will be placed in different priority queues according to the task priority policy settings and the type of SQL instructions to be executed. When there are tasks in the high priority queue, tasks in the low priority queue will not be executed.
[0034] In general, when there are tasks to be executed in the task queue but there are no idle worker threads, new worker threads will be started to schedule these tasks. The number of worker threads will not exceed the upper limit specified by the thread pool; the parameter "thread_pool_max_threads" sets the maximum number of threads allowed to be created by the entire thread pool; when a worker thread is idle for longer than the time set by the parameter "thread_pool_idle_timeout", it will automatically exit.
[0035] However, if the execution times of the tasks being scheduled are generally long, and at the same time the number of worker threads has reached the upper limit; then the tasks in the task queue will not be scheduled and executed for a long time. Another similar situation is that when a large number of tasks continuously pour into the high-priority task queue, the tasks in the low-priority queue will also not be executed for a long time. This situation is a common phenomenon in concurrent task scheduling and is vividly called task "starvation".
[0036] In the existing database thread pool technology, the thread pool of MySQL has the problem of "starvation". To alleviate "starvation", it is necessary to relax the limit on the number of over-limit threads, or create connections through "extra port". However, if the over-limit threads and extra port are overused, the so-called "upper limit on the number of threads" limit of the thread pool becomes meaningless. Therefore, the existing database thread pool implementations in the public technology generally have the dilemma of "starvation" and the uncontrollable upper limit on the number of threads. And even when the number of thread pools is not limited, the timeout response mechanism controlled by the "thread_pool_stall_limit" parameter (default 10ms) will extend an SQL that originally only takes a few microseconds to more than 10ms (triggering the situation of using over-limit threads due to timeout), thereby causing a sharp jitter in the SQL response speed.
[0037] The core problem of the above-mentioned "starvation" phenomenon is actually that: a long-running SQL, or an SQL that is in a waiting state for a long time (such as thread suspension caused by lock waiting), cannot be swapped out from the thread currently running this SQL before this SQL is executed. That is to say, even if a worker thread is in a suspended (lock waiting) state during the execution of a certain SQL, this thread cannot be reused to schedule and execute other SQL tasks; to execute other SQLs simultaneously, only other threads can be used.
[0038] To better understand the traditional technology, some terms are introduced below:
[0039] MariaDB: One of the most popular open-source relational databases currently, which can be regarded as a branch of the MySQL database. It is made by the original developers of MySQL and is guaranteed to remain open-source forever.
[0040] Percona: An open-source relational database. The thread pool of Percona has enhanced functions and optimized performance on the basis of porting the source code of the MariaDB thread pool.
[0041] Thread pool: As the name implies, a thread pool is to create a number of executable threads in advance and put them into a pool (container). When a task needs to be executed, instead of creating a new thread for this task, the threads that have been created in the thread pool are used. Through the above solution, the number of thread creations and destructions is reduced, the scheduling burden is reduced, and thus the system performance is improved.
[0042] Binlog: Binlog is a binary format log file used to record the history of users' database update operations and is often used to implement incremental replication in a database master-slave architecture. Among them, the master database continuously generates binlog logs and synchronizes the incremental part to the slave database; while the slave database achieves master-slave consistency by continuously applying these logs.
[0043] Semi-sync: Semi-synchronous replication, a master-slave replication mode of MySQL, whose performance and reliability are both between full synchronous replication and full asynchronous replication. Different from full synchronous replication, semi-sync does not pursue real-time consistency of data visibility between the master and the slave, but only ensures that there will be no log loss between the master and the slave (that is, it ensures the ultimate consistency of data visibility between the master and the slave). By weakening the consistency requirement, the purpose of improving the master-slave replication performance is achieved.
[0044] Relay log: In a database master-slave synchronization solution based on binlog, the slave database (i.e., the binlog receiver) can achieve asynchronous log reception and application through a strategy called "relay log". When the slave database receives the binlog sent by the master database, it can land the log stream to a local file; and the background log application thread can continuously read these local log files to achieve asynchronous log application. The local log files generated by the above slave database are called "relay logs".
[0045] Group commit: When the database executes a commit operation, it needs to write logs, and the log files need to be written serially. In the scenario of a large number of concurrent writes, if each transaction writes the log once, the actual write speed will be slowed down to the speed of serial writing of the log file. Group commit is a performance optimization solution for the above problem. When there are a large number of concurrent writes, the logs of multiple transactions that are committed almost simultaneously can be merged, so that this group of transactions only needs to write the log once, thus improving the concurrent performance. In MySQL, each binlog group commit will select the transaction with the smallest transaction number in this group as the group leader, and this group leader is responsible for driving the entire commit process.
[0046] The present disclosure provides a database thread pool control method. Through dynamic library injection, without the database being aware, the connection processing threads in the database can be transparently replaced with coroutines, ensuring that the number of threads executing connection requests does not exceed the number of scheduling threads, thereby improving the concurrency performance of the database thread pool. As Figure 1 shown in FIG. 100, which illustrates the flow of an embodiment of the database thread pool control method according to the present disclosure. The database thread pool control method includes the following steps:
[0047] Step 101, load a dynamic library capable of replacing threads with coroutines in the operating system of the database to generate at least one coroutine scheduling thread.
[0048] In this embodiment, the coroutine scheduling thread is used to schedule at least one coroutine.
[0049] In this embodiment, the dynamic library is a library that supports the operation of the database and can provide a programming interface for the interaction between the database and the operating system during runtime.
[0050] In this embodiment, the dynamic library is a type of dynamic library. The compiled functions are stored in the dynamic library. The dynamic library provides an API interface to the database through functions, and the database calls the functions in the dynamic library through this API interface. Based on the native library, by hooking the library functions related to thread scheduling in the native library, a dynamic library can be obtained, and after the dynamic library is loaded, it can have a scheduling ability equivalent to that of threads.
[0051] In this embodiment, the C runtime library can be fully hooked to obtain a dynamic library. The dynamic library provides a runtime virtualization environment, and the database runs in this runtime virtualization environment, realizing the simulation of threads implemented in the native library in the form of coroutines, achieving the purpose of coroutine simulation of threads and scheduling coroutines through coroutine scheduling threads.
[0052] In this embodiment, loading the dynamic library is to dynamically inject the dynamic library into the database when the operating system starts the database. The runtime injection of the dynamic library means that before the operating system starts a database and loads the program into memory, a certain dynamic library is first loaded and the initialization code in this dynamic library is run. Through this program loading method, the pre-loaded dynamic library has the opportunity to construct a runtime virtualization environment in advance. In this runtime virtualization environment, the database or the operating system can call the functions in the dynamic library in real time. In this embodiment, after the database starts, the coroutine scheduling thread can be started accordingly.
[0053] In this embodiment, the coroutine scheduling thread includes a scheduler and a lock-free queue for placing at least one coroutine. The specific steps for the coroutine scheduling thread to schedule at least one coroutine are as follows: The scheduler obtains the coroutines in the ready state from the lock-free queue among at least one coroutine; synchronizes the coroutine context of the coroutine with the thread context in the thread control block; after the coroutine actively yields, the scheduler obtains the next coroutine in the ready state from the lock-free queue and synchronizes the coroutine context of the next coroutine with the thread context in the thread control block; after the next coroutine actively yields, the scheduler continues to obtain coroutines from the lock-free queue and synchronize the thread control block until there are no coroutines in the lock-free queue.
[0054] In this embodiment, the thread control block is the data structure of the thread in the native runtime library, called "Thread Control Block" (TCB for short), that is, the context structure of the thread. dtv and specific array are the data structures for storing TLS data in the TCB. dtv: used to store the TLS variables defined in the encoding stage. This data will increment as the database loads new dynamic runtime libraries because there may also be TLS variables in the dynamic runtime libraries.
[0055] specific: Dynamically created TLS (where the library functions for creating and deleting TLS keys are pthread_key_create and pthread_key_delete respectively; and the library functions for reading and modifying TLS values are pthread_getspecifix and pthread_setspecific respectively). This type of TLS is maintained by an array of pointers (specific arrays), so there is an upper limit on the number (Linux supports creating up to 1024 dynamic TLSs at most).
[0056] In this embodiment, when the source code of the database is open-source code, the dynamic runtime library is obtained by directly modifying and recompiling the source code of the database. After loading the dynamic runtime library, the database can run in a new virtualized environment. Optionally, when the database supports plug-in development, the plug-in interface of the plug-in can be used to implement connection response. When the connection management plug-in responds to a new connection, it calls the hook function for creating coroutines to achieve the purpose of converting the connection thread to a coroutine. Among them, the hook function for creating coroutines is injected when the database starts, and the timing of loading the plug-in can be at any stage desired by the user.
[0057] Step 102: Receive the connection request sent by the client to the database.
[0058] In this embodiment, the connection request is the connection request sent by the client to the database after the dynamic runtime library is run.
[0059] In this embodiment, in order to separate the coroutine scheduling thread from other background threads of the database, when the dynamic library is mounted during the database startup phase, it is necessary to set the default thread creation mode through environment variables and set the default behavior to start the native system thread.
[0060] Step 103: Detect whether the request for the database to create a new thread is a request for processing a connection request.
[0061] In this embodiment, after the dynamic library is loaded, the program of the hook function in the dynamic library directly replaces the connection manager module (connection handler) in the database. The operation of this hook function can directly convert the newly created connection processing thread (session) in the database into a coroutine. When the dynamic library is loaded in the form of a plugin, the connection handler is replaced by mounting a thread pool plugin. After the thread pool plugin replaces the connection manager module, the newly created connection processing thread in the data is directly converted into a coroutine by this thread pool plugin. When unloading this thread pool plugin, it is necessary to ensure that all coroutine-based connection processing threads have been closed, otherwise an error of "plugin resource busy" will be reported.
[0062] In this embodiment, the request to create a new thread is a request from the database to create a thread. After the database receives a connection request from the client, it will create a corresponding connection processing thread for each client connection. The request to create a connection processing thread is the request to create a new thread, that is, a request to create a new thread is sent to the application programming interface of the dynamic library. The execution entity on which the database thread pool control method of this embodiment runs can, after obtaining that the request to create a new thread is a request for processing a connection request, construct a connection processing thread and establish a connection with the client through the constructed connection processing thread. Optionally, the execution entity can also, after obtaining that the request to create a new thread is a request for processing a connection request, use a coroutine to replace the constructed connection processing thread and establish a connection with the client by scheduling and executing the coroutine through the coroutine scheduling thread.
[0063] Step 104: In response to detecting that the request for the database to create a new thread is a request for processing a connection request, create a coroutine corresponding to the connection request, and schedule the coroutine through at least one coroutine scheduling thread to complete the access task corresponding to the connection request.
[0064] In this embodiment, by injecting a dynamic library to generate a coroutine scheduling thread, all threads in the database can be completely scheduled by the coroutine scheduling thread. At the same time, by utilizing the yieldability of the coroutine and the property of time-sharing and multiplexing the time slice of the scheduling thread, it can be ensured that the database will neither have the problem of task "starvation" nor the problem of response time jitter caused by the task not being scheduled for a long time.
[0065] In this embodiment, the process of handling the connection processing thread of a user (from connection creation, continuously receiving and executing SQL until connection closure) is regarded as an access task, and the coroutine created corresponding to the connection request is the carrier of this task. For connection requests, coroutines can be continuously created, and the only constant is the coroutine scheduling thread. Therefore, the present disclosure needs to schedule continuously created coroutines through a limited number of coroutine scheduling threads.
[0066] As Figure 2 shown, a schematic structural diagram of the database of the present disclosure is shown. In Figure 2 , the method of creating a new connection in the database is as follows: after receiving a thread construction request for handling a connection, through the HOOK of the library function for creating a thread in the native runtime library (such as the pthread_create() hook in Figure 2 ), the connection processing thread of the database is converted into a coroutine. The generated coroutine can be used to handle connections in the database, and the generated coroutine can be scheduled by multiple coroutine scheduling threads, achieving the effect of a database "thread pool". In this embodiment, the thread construction request for handling a connection is a request from the database to create a new thread for handling a connection request. After this request is approved, the database can create a connection processing thread for handling the client connection request, and the connection processing thread is a thread for handling the client connection request; further, through the hook function in the dynamic runtime library, a coroutine replacing the connection processing thread can be directly constructed after there is a thread construction request for handling a connection.
[0067] The database thread pool control method provided by the embodiment of the present disclosure is as follows: First, load a dynamic runtime library capable of replacing a thread with a coroutine in the operating system of the database to generate at least one coroutine scheduling thread, and the coroutine scheduling thread is used to schedule at least one coroutine; second, receive a connection request sent by a client to the database; third, detect whether the request from the database to create a new thread is a request for handling a connection request; finally, in response to detecting that the request from the database to create a new thread is a request for handling a connection request, create a coroutine corresponding to the connection request, and schedule the coroutine through at least one coroutine scheduling thread to complete the access task corresponding to the connection request. Thus, through the injection method of the dynamic runtime library, the connection processing thread in the database for handling connections is transparently replaced with a coroutine. The created coroutine corresponding to the connection request runs in a time-sharing call form. When a time-consuming operation such as suspension and waiting occurs in a certain coroutine, the current coroutine scheduling thread can be actively relinquished, and the coroutine scheduling thread can swap in another executable coroutine, which can solve the problems of increased delay of low-priority tasks and jitter in task response speed, and improve the concurrency performance of the database.
[0068] For the above embodiments, by injecting and running a dynamic runtime library, all connection processing threads of the database can be converted into connection processing coroutines, and the connection processing coroutines are completely scheduled by the coroutine scheduling threads, implementing a thread model similar to the thread pool solution of the native runtime library. However, there are two different types of loads during the operation of the database, and this load can generally be divided into compute-intensive and I / O-intensive. As Figure 3 shown, in a three-node MySQL database cluster with a master-slave architecture of one master (Z) and two slaves (C1, C2), the time series of SQL execution on the master node includes: receiving an SQL instruction -> executing the SQL instruction -> writing the modified content to the binlog -> incrementally synchronizing the binlog to the two slave nodes -> completing the SQL submission. Currently, most MySQL master-slave replications are deployed using the MySQL cluster and high-availability semi-synchronous mode. In this mode, the process of the master-slave replication stage (when group commit (binlog group commit) is enabled, the following describes the process of the group leader) is as follows:
[0069] 1) The master database writes the transaction to the binlog;
[0070] 2) The master database transmits the binlog to the slave database;
[0071] 3) The slave database receives the binlog sent by the master database and lands its content to the relay log ( Figure 3 receive the relay log in), and then sends an acknowledgment response to the master database;
[0072] 4) The master database waits for the acknowledgment character response from the slave database until all slave databases have responded;
[0073] 5) The master database completes the transaction submission and returns "commit OK" to the client.
[0074] A MySQL connection processing coroutine (obtained by transforming a connection processing thread into a coroutine) will repeat the above process cyclically to execute the SQL statements initiated by the client. From the entire process, it can be seen that only the SQL instruction execution stage is computationally intensive, with a relatively high CPU occupancy rate at this time; other stages are all about initiating or waiting for the completion of I / O, that is, I / O-intensive loads. I / O-intensive loads themselves consume very little CPU, but due to the need for frequent I / O waiting, a large number of coroutine swap-in / swap-out operations need to be triggered. If I / O-intensive loads and computationally intensive loads are executed in the same group of scheduling threads, the frequent swap-in / swap-out operations of I / O-intensive loads will disrupt the scheduling rhythm of computationally intensive tasks, increase the scheduling burden, and reduce the overall performance. Because coroutines rely on time-sharing to multiplex the time slices of scheduling threads to simulate parallelism, and the scheduling threads also consume CPU time for swap-in / swap-out; therefore, the more CPU time the scheduling threads spend on swap-in / swap-out, the less CPU time is available for executing computational tasks.
[0075] In this embodiment, after the dynamic runtime library is loaded, the management of all threads in the database defaults to converting all threads into coroutines, resulting in different types of coroutines (such as the I / O coroutines for master-slave replication, the coroutines for receiving response signals, etc.), as well as different types of loads in database commands, all being scheduled by the same batch of coroutine scheduling threads, leading to a mixed scheduling of different types of coroutine loads. I / O-intensive loads need to wait for I / O in a swap-out / swap-in manner, which will disrupt the scheduling rhythm of computationally intensive loads and increase the burden on the threads to handle coroutine swap-in / swap-out.
[0076] To solve the above performance problems, the present disclosure provides another embodiment of a database thread pool control method, which includes the following steps: loading a dynamic runtime library capable of replacing threads with coroutines in the operating system of the database to generate at least one coroutine scheduling thread for scheduling at least one coroutine; dividing the at least one coroutine scheduling thread into an I / O intensive scheduling thread and a compute intensive scheduling thread; receiving a connection request sent by a client to the database and detecting whether the connection request is a thread construction request for processing the connection; in response to detecting that the connection request is a thread construction request for processing the connection, creating a coroutine corresponding to the connection request and detecting whether the coroutine corresponding to the connection request is in a state between a first state and a second state, where the first state is the state of the coroutine when it is waiting to execute a data packet of a database command, the data packet has arrived, and the coroutine needs to be awakened; the second state is the state of the coroutine located in the compute intensive scheduling thread and the coroutine initiates a specific write request for a specific file; if it is detected that the coroutine corresponding to the connection request is in a state between the first state and the second state, scheduling the coroutine corresponding to the connection request using the compute intensive scheduling thread among the at least one coroutine scheduling thread; if it is detected that the coroutine corresponding to the connection request is not in a state between the first state and the second state, scheduling the coroutine corresponding to the connection request using the I / O intensive scheduling thread among the at least one coroutine scheduling thread.
[0077] In this embodiment, the coroutine scheduling threads are divided into two groups: compute intensive scheduling threads and I / O intensive scheduling threads. The compute intensive scheduling threads are used to schedule the execution of compute intensive loads, and the I / O intensive scheduling threads are used to schedule the execution of I / O intensive loads.
[0078] In this embodiment, based on a preset division rule, the at least one coroutine scheduling thread can be divided into an I / O intensive scheduling thread and a compute intensive scheduling thread, where the preset division rule is that the ratio of the number of I / O intensive scheduling threads to the number of compute intensive scheduling threads is a fixed value (such as 1:4). Optionally, the above preset division rule can also be: determining the type of the database, and based on the type of the database, determining the ratio of the number of I / O intensive scheduling threads to the number of compute intensive scheduling threads. For a database with more I / O operations, in the setting of the division rule, the ratio of the number of I / O intensive scheduling threads can be set to a larger value; for a database with more compute operations, through the setting of the division rule, the ratio of the number of compute intensive scheduling threads can be set to a larger value.
[0079] In this embodiment, the coroutine corresponding to the connection request is the coroutine that executes the connection request, and this coroutine can be in different stages of executing the connection request. For example, receiving a database instruction, executing a database instruction, submitting the instruction processing result to other libraries, and returning the database instruction execution result to the client stage. Among them, the state between the first state and the second state belongs to the stage of executing the database instruction. A large number of computational operations are required in this stage of executing the database instruction. Migrating the coroutine to a compute-intensive scheduling thread for scheduling can achieve separation from the I / O-intensive load.
[0080] In this embodiment, the state between the first state and the second state is used to define the stage between the point where the operation of waiting for the data packet of the database command to be executed is about to be awakened and the point where a specific write operation occurs on a specific file. In the state of waiting for the data packet of the database command to be executed, when the data packet has arrived and the coroutine is about to be awakened, it needs to be placed in a compute-intensive scheduling thread.
[0081] For the MySQL database, the state between the first state and the second state means: the state where the data of the SQL request packet has arrived and the I / O operation of waiting for the SQL request packet is about to be awakened from the waiting state. By monitoring the state between the first state and the second state, the coroutine in this state can be migrated to a compute-intensive scheduling thread. When the coroutine resumes, it will just execute in the compute-intensive scheduling thread and start processing the just-received SQL request packet.
[0082] Taking the MySQL database as an example, the working principle of the execution entity on which the database thread pool control method of the present disclosure runs is as follows:
[0083] 1) For a newly created connection, since the work of performing handshake confirmation and connection context initialization (i.e., the stage of creating a connection) needs to communicate with the client several times during this period, which belongs to I / O-intensive operations, the connection processing coroutine corresponding to this new connection needs to be handed over to an I / O-intensive scheduling thread for processing. Place the connection processing coroutine in the I / O-intensive scheduling thread so that the I / O-intensive scheduling thread schedules the coroutine corresponding to this new connection.
[0084] 2) After the connection is established, the connection processing coroutine of MySQL needs to wait for the receive operation to receive the SQL instruction data packet sent by the client (MySQL waits through poll implementation); when poll ends waiting (i.e., there is a data packet to be received) and is about to awaken this connection processing coroutine, this connection processing coroutine can be migrated to a compute-intensive scheduling thread. During the execution of the SQL operation, the current coroutine always remains in the compute-intensive scheduling thread.
[0085] 3) When the connection processing coroutine calls the write operation and starts writing to the binlog file, it means that the connection processing coroutine begins to enter the master-slave synchronization and transaction submission stage (if binlog group commit is enabled, it means this coroutine is the "group leader"); at this time, before completing the submission of the file write I / O request and yielding the coroutine to enter the I / O waiting state, the current connection processing coroutine is migrated to the I / O-intensive scheduling thread.
[0086] From the binlog writing, binlog sending, ack waiting, and completing the transaction submission, until there is a new SQL instruction that can be received, the current connection processing coroutine always remains in the I / O-intensive scheduling thread.
[0087] Based on the above processes 1)-3), repeating this cycle until the connection processing thread exits, the separation of I / O-intensive load and compute-intensive load can be achieved.
[0088] In this embodiment, the logic of migrating the scheduling thread can be injected through the callback interface of the dynamic runtime library. The specific logic is as follows:
[0089] First, assume that 40 coroutine scheduling threads are started when the dynamic runtime library is mounted; since the CPU occupancy rate of I / O-intensive tasks is very low, fewer threads are required; the coroutine scheduling thread IDs from 0 to 31 of these 32 scheduling threads are designated as compute-intensive scheduling threads, and the coroutine scheduling thread IDs from 32 to 39 of these 8 scheduling threads are designated as I / O-intensive scheduling threads.
[0090] Secondly, when migrating the coroutine to different coroutine scheduling threads, the thread pool plugin needs to use a load balancing algorithm to balance the migrated coroutine scheduling threads to avoid load skew. Optionally, in the MySQL database, the hash value of the connection processing thread ID can be used as the selection factor for the scheduling thread to implement the load balancing algorithm.
[0091] Based on the above premise, the present disclosure only needs to implement the callback function for waking up the coroutine operation and the callback function for the write operation. These two callback functions can implement the coroutine grouping scheduling mechanism described above.
[0092] When performing the file write operation, if it is determined that the current coroutine is writing to the binlog file, its scheduling thread ID is set to a value between 32 and 39 (i.e., I / O-intensive). And before waking up the coroutine, if it is determined that the coroutine is about to enter the SQL instruction execution stage, its scheduling thread ID is set to a value between 0 and 31.
[0093] The database thread pool control method provided by the embodiments of the present disclosure can divide the coroutine scheduling threads into two groups, divert the I / O intensive scheduling load to dedicated I / O scheduling threads, reduce the scheduling resource consumption of the compute intensive scheduling threads, and improve the concurrency performance of the database.
[0094] In some alternative implementation manners of the disclosure, loading a dynamic runtime library capable of replacing threads with coroutines in the operating system of the database to generate at least one coroutine scheduling thread includes: when it is determined that the database cannot modify the source code and does not have a connection management plug-in mechanism, starting the database; loading and initializing the dynamic runtime library to generate at least one coroutine scheduling thread, where the dynamic runtime library has a hook function for creating a thread, and the hook function for creating a thread is used to replace the connection processing thread generated by the native runtime library of the database with a coroutine; when initializing the database, overloading the hook function for creating a thread to determine whether the currently created thread is a connection processing thread through the hook function for creating a thread, and when the currently created thread is a connection processing thread, converting the connection processing thread into a coroutine.
[0095] In this embodiment, in the hook function for creating a thread, it is monitored whether the currently created thread is a connection processing thread. When the currently created thread is a connection processing thread, the thread descriptor is replaced with a coroutine context structure, and the currently running thread or coroutine is marked through a global variable with thread-local constraints. The synchronization management module is used to manage the thread-local storage information in the coroutine context structure, and the synchronization management module is used to synchronize the thread-local storage of the coroutine when the coroutine scheduling thread schedules the coroutine.
[0096] In this embodiment, the coroutine context structure (hereinafter referred to as the COCTX structure) is a structure for placing the coroutine context (hereinafter referred to as the COCTX), which is used to maintain the context of the coroutine and has a role similar to that of a thread descriptor (or a thread handle). To provide compatibility with thread behavior, it is necessary to hook the library functions for creating a thread and obtaining a thread descriptor in the native runtime library, and replace the thread descriptor with the COCTX. Taking Linux as an example, its thread descriptor is called "TCB", and its implementation is a structure named "pthread". The calls for creating a thread and obtaining a thread descriptor in Linux are respectively:
[0097] pthread_create: Creates a thread and returns a thread descriptor, and the value of this thread descriptor is the address of the TCB structure. In this embodiment, the hook of the thread creation function instead returns a pointer to the COCTX.
[0098] pthread_self: Obtains the descriptor of the current thread, and also replaces it with a pointer to the COCTX.
[0099] In this embodiment, a global TLS variable (a global variable with thread-local constraints) can be used to obtain the context of the current coroutine, and its declaration is as follows:
[0100] extern __thread COCTX* _current_coctx;
[0101] In this embodiment, COCTX has the following four types:
[0102] Coroutine COCTX: corresponding to an actual coroutine;
[0103] Global COCTX: The _current_coctx of the main thread will be set to global COCTX, and this COCTX will be created when the dynamic runtime library is just loaded;
[0104] Scheduler COCTX: Each coroutine scheduling thread (the thread that runs the coroutine) will have a default COCTX. When no coroutine is in the ready state or in the intermediate state of coroutine switching, the _current_coctx of the current thread will be set to scheduler COCTX;
[0105] Single COCTX: When creating a native system thread, a virtual COCTX will be created for it.
[0106] As described above, the hook function of pthread_self actually returns the value of _current_coctx. In the program, by judging the type of the current COCTX, it is possible to know which type of thread and which running state it is in.
[0107] In this embodiment, the content stored in the COCTX structure includes: the coroutine stack and TLS. The dynamic runtime library allocates an independent stack for each coroutine, so it can completely simulate the behavior of a thread (including the memory size allocated in the stack and the call stack depth).
[0108] If the coroutine cannot completely simulate the TLS mechanism of the thread, it will cause the coroutine to be unable to safely access variables with TLS constraints. In this embodiment, through the synchronization management module (hereinafter referred to as co_tls), the encapsulation of TLS management is realized, and the capabilities provided by co_tls are crucial for "transparent" simulation of threads. Taking Linux as an example, the following two types of TLS are stored in its TCB: dtv and specific.
[0109] Support of co_tls in this disclosure for specific: A data structure similar to specific arrays in TCB needs to be maintained in co_tls. When a newly created coroutine is first swapped in for execution, the specific in the TCB of its affiliated scheduling thread will be copied. In addition, the library functions for managing specific need to be hooked. The Linux library functions were listed above, and there are similar functions in Windows, namely: TlsAlloc, TlsFree, TlsGetValue, and TlsSetValue.
[0110] Support of co_tls in this disclosure for dtv: Similarly, when a newly created coroutine is first scheduled for execution, the dtv in the TCB also needs to be copied. However, different from specific, the content of specific in co_tls does not need to be synchronized with the TCB anymore; but due to the possible dynamic loading of other dynamic runtime libraries during runtime, the dtv in co_tls needs to be incrementally synchronized with the dtv in the TCB. An incremental backup of the TCB dtv is stored in the scheduler COCTX to describe the incremental part of the dtv generated each time a dynamic runtime library is loaded. At the same time, the library function calls for loading dynamic runtime libraries need to be hooked (this library function is called dlopen in Linux, and corresponds to LoadLibrary in Windows). Taking Linux as an example, a data structure called "link_map" describes all dynamic runtime library information. Combining link_map and the dtv incremental backup, the differences between the current coroutine and the dtv increment can be parsed. For the merging of dtv increments, a "lazy" synchronization scheme is adopted, that is, it is judged whether the dtv needs to be synchronized when the coroutine is about to be swapped in. If dlopen is called in a certain coroutine, it is necessary to identify _current_coctx as the coroutine type in the hook of dlopen and immediately synchronize the dtv for the current coroutine.
[0111] In this embodiment, by creating a hook function for a thread, a coroutine that is exactly the same as the thread in terms of capabilities can be simulated. The process of coroutine switching is as follows: First, in the initial state of the coroutine scheduling thread, _current_coctx is schedulerCOCTX; then, when a coroutine needs to be resumed, it is checked whether there are differences between this coroutine and the dtv incremental backup (synchronization is required if there are differences), and after the difference synchronization is completed, _current_coctx is set to the context of the current coroutine; finally, when this coroutine requests to be swapped out, _current_coctx is restored to scheduler COCTX. The entire coroutine switching process is executed entirely in the user space without any form of interaction with the operating system, thus maintaining the lightweight feature of the coroutine.
[0112] This embodiment realizes the pure user-space TLS switching of coroutines, maintaining the lightweight feature of coroutine switching while maintaining the cross-coroutine security of TLS (taking into account high performance and "transparent" virtualization).
[0113] The method for generating a coroutine scheduling thread provided in this embodiment, when the source code of the database cannot be modified and there is no connection management plug-in mechanism, by injecting a dynamic runtime library with a hook function for creating a thread into the started database, and overloading the hook function for creating a thread during the initialization of the database, the hook function for creating a thread can intercept the request for creating a connection processing thread and convert the connection processing thread into a coroutine. The method provided in this embodiment provides a reliable implementation for converting a connection processing thread into a coroutine.
[0114] In some disclosed optional implementation manners, the above-mentioned loading of a dynamic runtime library capable of replacing a thread with a coroutine in the operating system of the database and generating at least one coroutine scheduling thread includes: in response to the database having a connection management plug-in mechanism, starting the database; loading and initializing the dynamic runtime library to generate at least one coroutine scheduling thread; initializing the database; loading and initializing the plug-in so that the plug-in receives a connection request sent to the database, and when the thread construction request of the database is a request for processing the connection request, controlling the hook function for creating a thread in the dynamic runtime library to work. The hook function for creating a thread is used to determine whether the currently created thread is a connection processing thread, and when the currently created thread is a connection processing thread, converting this connection processing thread into a coroutine.
[0115] In this embodiment, the connection management plug-in mechanism is a mechanism for expanding the functions of the database through a plug-in without modifying the database, and it is also a solution without modifying the source code of the database.
[0116] In this embodiment, the plug-in is a third-party device located in the database and the dynamic runtime library. The plug-in can both call the application interfaces of the dynamic runtime library and the database. The plug-in receives connection requests and database thread construction requests by calling the application interfaces of the database, detects whether the database thread construction request is a request for processing connection requests, and when the database thread construction request is a request for processing connection requests, calls the application interfaces of the dynamic runtime library. By calling the application interfaces of the dynamic runtime library, the hook function for creating threads is made to work, and the hook function for creating threads determines the connection processing thread and converts the connection processing thread into a coroutine.
[0117] In this embodiment, the hook function for creating threads is a function obtained by processing the function for creating threads in the C library through the HOOK mechanism. The specific content of the hook function for creating threads is as described in the above embodiment and will not be elaborated here.
[0118] The method for generating a coroutine scheduling thread provided in this embodiment, when the database has a connection management plug-in mechanism, accesses the plug-in, receives connection requests through the plug-in, and when the connection request is a thread construction request for user connection processing, calls the hook function for creating threads in the dynamic runtime library to work and converts the connection processing thread into a coroutine. The method provided in this embodiment provides another reliable implementation for converting the connection processing thread into a coroutine.
[0119] In some alternative implementation manners of the present disclosure, the above-mentioned scheduling the coroutine corresponding to the connection request by using the IO-intensive scheduling thread in at least one coroutine scheduling thread when it is detected that the coroutine corresponding to the connection request is not in a state between the first state and the second state includes: in response to the coroutine corresponding to the connection request being in the stage of creating a connection, placing the coroutine on the current IO-intensive scheduling thread, and the current IO-intensive scheduling thread is determined based on the load balancing algorithm; in response to the coroutine corresponding to the connection request being in a specific write operation on a specific file and before the submission of the IO request for writing the specific file is completed and the coroutine is yielded to enter the IO waiting state, migrating the coroutine to the current IO-intensive scheduling thread.
[0120] In this embodiment, the write operations on the specific file and the characteristic file may vary according to the type of the database. For example, for the MySQL database, the specific file is the binlog file; for the openGauss database, the specific file is the xlog file. For various specific files, various types of data have corresponding specific write operations.
[0121] The method for scheduling coroutines provided by this alternative implementation migrates the coroutine to an I / O intensive scheduling thread when the coroutine in the database is in the stage of creating a connection; and migrates the coroutine to an I / O intensive scheduling thread before the coroutine is in a specific write operation on a specific file, completes the submission of the I / O request for the specific file, and enters the I / O wait state. Thus, the tasks in the I / O intensive state are diverted to a dedicated I / O scheduling thread, reducing the resource consumption of the computation intensive scheduling thread and improving the concurrency performance of the database.
[0122] In some alternative implementations of the present disclosure, when the database is a MySQL database, before the above-mentioned coroutine corresponding to the connection request is in a specific write operation on a specific file, completes the submission of the write I / O request for the specific file, and yields the coroutine to enter the I / O wait state, migrating the coroutine to the current I / O intensive scheduling thread includes:
[0123] Before the coroutine corresponding to the connection request is in a write operation on the binary log file, completes the submission of the write file I / O request, and yields the coroutine to enter the I / O wait state, migrating the coroutine to the current I / O intensive scheduling thread.
[0124] The method for migrating coroutines provided by this embodiment migrates the coroutine to the current I / O intensive scheduling thread based on the write operation of a specific binary log file in the MySQL database when the database is a MySQL database, providing a reliable implementation for the allocation of coroutines in the MySQL database.
[0125] In some embodiments of the present disclosure, the above-mentioned database thread pool control method further includes: detecting whether there is a coroutine for driving batch submission in the I / O intensive scheduling thread; if there is a coroutine for driving batch submission in the I / O intensive scheduling thread, migrating the coroutine woken up by the coroutine for driving batch submission to the I / O intensive scheduling thread, and the I / O intensive scheduling thread into which the coroutine woken up by the coroutine for driving batch submission migrates is determined based on the load balancing algorithm.
[0126] In this embodiment, a coroutine wake-up callback function can be added to the dynamic runtime library, and there is corresponding judgment logic in the callback function. The judgment logic is: for a coroutine that is currently performing an operation to wake up other coroutines, if it itself is in the I / O intensive scheduling thread, the coroutine woken up by it also needs to be migrated to the I / O intensive scheduling thread.
[0127] The database thread pool control method provided by this embodiment migrates the coroutine woken up by the coroutine for driving batch submission to the current I / O intensive scheduling thread when there is a coroutine for driving batch submission in the I / O intensive scheduling thread, which can improve the coroutine scheduling efficiency.
[0128] In some alternative implementations of the present disclosure, the above database is a MySQL database with group commit enabled. Detecting whether there is a coroutine that drives batch commit in the IO-intensive scheduling thread includes: detecting whether there is a group leader coroutine that drives the group commit process for writing to the binary log file in the IO-intensive scheduling thread; if there is a coroutine that drives batch commit in the IO-intensive scheduling thread, migrating the coroutines woken up by this coroutine to the IO-intensive scheduling thread includes: if it is detected that there is a group leader coroutine for writing to the binary log file, migrating the member coroutines woken up by this group leader coroutine to the IO-intensive scheduling thread, and the IO-intensive scheduling thread into which each member coroutine migrates is determined based on the load balancing algorithm.
[0129] In this embodiment, in the IO-intensive task, only the group leader coroutine of the binary log file group commit will wake up all other tasks in the current commit group after receiving the confirmation message from the slave; and at this time, the woken-up tasks must also be in the commit state, so they need to be switched to the IO-intensive scheduling thread.
[0130] The method for migrating coroutines provided in this embodiment, when the database is a MySQL database, determines the group leader coroutine based on the write operation of the specific binary log file in the MySQL database, and migrates the member coroutines woken up by this group leader coroutine to the current IO-intensive scheduling thread, providing a reliable implementation for the allocation of member coroutines in the MySQL database.
[0131] Further referring to Figure 4 , as an implementation of the database thread pool control method shown in the above figures, the present disclosure provides an embodiment of a database thread pool control device. This device embodiment corresponds to Figure 1 the method embodiment shown, and this device can be specifically applied to various electronic devices.
[0132] As shown in Figure 4As shown in the figure, an embodiment of the present disclosure provides a database thread pool control device 400, which includes a loading unit 401, a receiving unit 402, a detection unit 403, and a creation unit 404. Among them, the above-mentioned loading unit 401 can be configured to load a dynamic runtime library capable of replacing threads with coroutines in the operating system of the database, generate at least one coroutine scheduling thread, and the coroutine scheduling thread is used to schedule at least one coroutine; the above-mentioned receiving unit 402 can be configured to receive a connection request sent by a client to the database; the above-mentioned detection unit 403 can be configured to detect whether the request for the database to create a new thread is a request for processing a connection request; the above-mentioned creation unit 404 can be configured to, in response to detecting that the request for the database to create a new thread is a request for processing a connection request, create a coroutine corresponding to the connection request, and schedule the coroutine through at least one coroutine scheduling thread to complete the access task corresponding to the connection request.
[0133] In this embodiment, in the database thread pool control device 400, the specific processing of the loading unit 401, the receiving unit 402, the detection unit 403, and the creation unit 404 and the technical effects brought by them can be respectively referred to Figure 1 Steps 101, 102, 103, and 104 in the corresponding embodiments.
[0134] In some embodiments, the above-mentioned loading unit 401 is configured to: when the database cannot modify the source code and does not have a connection management plug-in mechanism, start the database; load and initialize the dynamic runtime library, generate at least one coroutine scheduling thread, the dynamic runtime library has a hook function for creating threads, and the hook function for creating threads is used to replace the connection processing thread generated by the native runtime library of the database with a coroutine; when the database is initialized, reload the hook function for creating threads to determine whether the currently created thread is a connection processing thread through the hook function for creating threads, and when the currently created thread is a connection processing thread, convert the connection processing thread into a coroutine.
[0135] In some embodiments, the above-mentioned loading unit 401 is configured to: when the database has a connection management plug-in mechanism, start the database; load and initialize the dynamic runtime library, generate at least one coroutine scheduling thread; initialize the database; load and initialize the plug-in so that the plug-in receives the connection request sent to the database, and when the thread construction request of the database is a request for processing the connection request, control the hook function for creating threads in the dynamic runtime library to work, and the hook function for creating threads is used to determine whether the currently created thread is a connection processing thread, and when the currently created thread is a connection processing thread, convert the connection processing thread into a coroutine.
[0136] In some embodiments, the above-mentioned device further includes: a partitioning unit (not shown in the figure), and the partitioning unit is configured to partition at least one coroutine scheduling thread into an I / O-intensive scheduling thread and a compute-intensive scheduling thread; the above-mentioned creating unit 404 is further configured to: detect whether the coroutine corresponding to the connection request is in a state between a first state and a second state, where the first state is the state of the coroutine waiting to execute a database command packet, the packet has arrived, and the coroutine needs to be woken up; the second state is the state of the coroutine located in the compute-intensive scheduling thread and the coroutine initiates a specific write request for a specific file; if it is detected that the coroutine corresponding to the connection request is in a state between the first state and the second state, schedule the coroutine corresponding to the connection request using the compute-intensive scheduling thread among at least one coroutine scheduling thread; if it is detected that the coroutine corresponding to the connection request is not in a state between the first state and the second state, schedule the coroutine corresponding to the connection request using the I / O-intensive scheduling thread among at least one coroutine scheduling thread.
[0137] In some embodiments, the above-mentioned creating unit 404 is further configured to: in response to the coroutine corresponding to the connection request being in the stage of creating a connection, place the coroutine on the current I / O-intensive scheduling thread, and the current I / O-intensive scheduling thread is determined based on the load balancing algorithm; in response to the coroutine corresponding to the connection request being in a specific write operation on a specific file and before completing the submission of the I / O request for writing the specific file and yielding the coroutine to enter I / O waiting, migrate the coroutine to the current I / O-intensive scheduling thread.
[0138] In some embodiments, the above-mentioned database is a MySQL database, and the above-mentioned creating unit 404 is further configured to: in response to the coroutine corresponding to the connection request being in a write operation on a binary log file and before completing the submission of the I / O request for writing the file and yielding the coroutine to enter I / O waiting, migrate the coroutine to the current I / O-intensive scheduling thread.
[0139] In some embodiments, the above-mentioned device further includes: a batch driving unit (not shown in the figure), and the batch driving unit is configured to: detect whether there is a coroutine for driving batch submission in the I / O-intensive scheduling thread; if there is a coroutine for driving batch submission in the I / O-intensive scheduling thread, migrate the coroutine woken up by the coroutine for driving batch submission to the I / O-intensive scheduling thread, and the I / O-intensive scheduling thread into which the coroutine woken up by the coroutine for driving batch submission migrates is determined based on the load balancing algorithm.
[0140] In some embodiments, the above database is a MySQL database with group commit enabled, and the batch driving unit is further configured to: detect whether there is a leading coroutine in the IO-intensive scheduling thread that drives the group commit process for writing to the binary log file; if a group leader coroutine for writing to the binary log file is detected, migrate the member coroutines that wake up the group leader coroutine to the IO-intensive scheduling thread, and the IO-intensive scheduling threads into which each member coroutine migrates are determined based on the load balancing algorithm.
[0141] The database thread pool control device provided by the embodiments of the present disclosure, first, the loading unit 401 loads a dynamic runtime library capable of replacing threads with coroutines in the operating system of the database to generate at least one coroutine scheduling thread, and the coroutine scheduling thread is used to schedule at least one coroutine; second, the receiving unit 402 receives a connection request sent by the client to the database; third, the detection unit 403 detects whether the request for the database to create a new thread is a request for processing the connection request; finally, the creation unit 404, in response to detecting that the request for the database to create a new thread is a request for processing the connection request, creates a coroutine corresponding to the connection request, and schedules the coroutine through at least one coroutine scheduling thread to complete the access task corresponding to the connection request. Thus, the present disclosure transparently replaces the connection processing threads used for connection processing in the database with coroutines through the injection method of the dynamic runtime library. The created coroutines corresponding to the connection requests run in a time-sharing call form. When a time-consuming operation such as suspension and waiting occurs in a certain coroutine, the current coroutine scheduling thread can be actively relinquished, and another executable coroutine can be swapped in by the coroutine scheduling thread, which can solve the problems of increased delay of low-priority tasks and jitter in task response speed, and improve the concurrency performance of the database.
[0142] The following refers to Figure 5 , which shows a schematic structural diagram of an electronic device 500 suitable for implementing the embodiments of the present disclosure.
[0143] As Figure 5 shown, the electronic device 500 may include a processing device (such as a central processing unit, a graphics processing unit, etc.) 501, which can perform various appropriate actions and processes according to a program stored in a read-only memory (ROM) 502 or a program loaded from a storage device 508 into a random access memory (RAM) 503. In the RAM 503, various programs and data required for the operation of the electronic device 500 are also stored. The processing device 501, the ROM 502, and the RAM 503 are connected to each other through a bus 504. An input / output (I / O) interface 505 is also connected to the bus 504.
[0144] Typically, the following devices can be connected to the I / O interface 505: input devices 506 including, for example, a touch screen, a touchpad, a keyboard, a mouse, etc.; output devices 507 including, for example, a liquid crystal display (LCD), a speaker, a vibrator, etc.; storage devices 508 including, for example, magnetic tapes, hard disks, etc.; and a communication device 509. The communication device 509 can allow the electronic device 500 to communicate with other devices wirelessly or wiredly to exchange data. Although Figure 5 the electronic device 500 with various devices is shown, it should be understood that it is not required to implement or have all the shown devices. Instead, more or fewer devices can be implemented or had. Figure 5 Each block shown in
[0145] Specifically, according to an embodiment of the present disclosure, the process described above with reference to the flowchart can be implemented as a computer software program. For example, an embodiment of the present disclosure includes a computer program product, which includes a computer program carried on a computer-readable medium, and the computer program includes program codes for executing the method shown in the flowchart. In such an embodiment, the computer program can be downloaded and installed from a network through the communication device 509, or installed from the storage device 508, or installed from the ROM 502. When the computer program is executed by the processing device 501, the above functions defined in the method of the embodiment of the present disclosure are executed.
[0146] It should be noted that the computer-readable medium in the embodiments of the present disclosure can be a computer-readable signal medium, a computer-readable storage medium, or any combination of the two. A computer-readable storage medium can be, for example, but not limited to, an electrical, magnetic, optical, electromagnetic, infrared, or semiconductor system, apparatus, or device, or any combination of the above. More specific examples of the computer-readable storage medium can include, but are not limited to: an electrical connection with one or more wires, a portable computer disk, a hard disk, a random access memory (RAM), a read-only memory (ROM), an erasable programmable read-only memory (EPROM or flash memory), an optical fiber, a portable compact disk read-only memory (CD-ROM), an optical storage device, a magnetic storage device, or any suitable combination of the above. In the embodiments of the present disclosure, the computer-readable storage medium can be any tangible medium that contains or stores a program, and this program can be used by or in combination with an instruction execution system, apparatus, or device. In the embodiments of the present disclosure, a computer-readable signal medium can include a data signal propagated in a baseband or as part of a carrier wave, which carries computer-readable program code. Such a propagated data signal can take various forms, including but not limited to electromagnetic signals, optical signals, or any suitable combination of the above. A computer-readable signal medium can also be any computer-readable medium other than a computer-readable storage medium, and this computer-readable signal medium can send, propagate, or transmit a program for use by or in combination with an instruction execution system, apparatus, or device. The program code contained on the computer-readable medium can be transmitted using any appropriate medium, including but not limited to: wires, optical cables, RF (Radio Frequency), etc., or any suitable combination of the above.
[0147] The above computer-readable medium can be included in the server; or it can exist independently and not be assembled into the server. The above computer-readable medium carries one or more programs. When the above one or more programs are executed by the server, the server is caused to: load a dynamic runtime library capable of replacing threads with coroutines in the operating system of the database, generate at least one coroutine scheduling thread, and the coroutine scheduling thread is used to schedule at least one coroutine; receive a connection request sent by a client to the database; detect whether a request for the database to create a new thread is a request for processing the connection request; in response to detecting that the request for the database to create a new thread is a request for processing the connection request, create a coroutine corresponding to the connection request, and schedule the coroutine through at least one coroutine scheduling thread to complete the access task corresponding to the connection request.
[0148] Computer program code for performing the operations of the embodiments of the present disclosure may be written in one or more programming languages or combinations thereof. The programming languages include object-oriented programming languages such as Java, Smalltalk, C++, and also include conventional procedural programming languages such as the "C" language or similar programming languages. The program code may be executed entirely on the user's computer, partially on the user's computer, executed as a stand-alone software package, partially on the user's computer and partially on a remote computer, or entirely on a remote computer or server. In the case of a remote computer, the remote computer may be connected to the user's computer through any type of network, including a local area network (LAN) or a wide area network (WAN), or may be connected to an external computer (e.g., connected through the Internet using an Internet service provider).
[0149] The flowcharts and block diagrams in the accompanying drawings illustrate the possible architectures, functions, and operations of systems, methods, and computer program products according to various embodiments of the present disclosure. In this regard, each block in the flowchart or block diagram may represent a module, a program segment, or a portion of code that contains one or more executable instructions for implementing the specified logical function. It should also be noted that in some alternative implementations, the functions marked in the blocks may occur in a different order than marked in the accompanying drawings. For example, two consecutive blocks shown may actually be executed substantially in parallel, and they may sometimes be executed in the reverse order, depending on the functions involved. It should also be noted that each block in the block diagram and / or flowchart, and combinations of blocks in the block diagram and / or flowchart, may be implemented by a dedicated hardware-based system that performs the specified functions or operations, or may be implemented by a combination of dedicated hardware and computer instructions.
[0150] The units involved in the embodiments described in the present disclosure may be implemented in software or in hardware. The described units may also be provided in a processor. For example, it may be described as a processor including a loading unit, a receiving unit, a detecting unit, and a creating unit. Among them, the names of these units do not constitute a limitation on the unit itself in some cases. For example, the loading unit may also be described as a unit "configured to load a dynamic runtime library that can replace threads with coroutines in the operating system of a database and generate at least one coroutine scheduling thread".
[0151] The above description is only a preferred embodiment of the present disclosure and an explanation of the applied technical principles. Those skilled in the art should understand that the scope of the invention involved in the embodiments of the present disclosure is not limited to the technical solutions formed by the specific combination of the above technical features, but should also cover other technical solutions formed by any combination of the above technical features or their equivalent features without departing from the above inventive concept. For example, the technical solutions formed by mutually replacing the above features with the technical features (but not limited to) disclosed in the embodiments of the present disclosure that have similar functions.
Claims
1. A method for controlling a database thread pool, the method comprising: Loading a dynamic runtime library capable of replacing a thread with a coroutine in an operating system of the database, generating at least one coroutine scheduling thread, wherein the coroutine scheduling thread is used to schedule at least one coroutine; Receiving a connection request sent by a client to the database; Detecting whether the request of the database to create a new thread is a request to process the connection request; In response to detecting that the request by the database to create a new thread is a request to process the connection request, creating a coroutine corresponding to the connection request; Scheduling the coroutine to complete the access task corresponding to the connection request through the at least one coroutine scheduling thread includes: if it is detected that the coroutine corresponding to the connection request is not in a state between the first state and the second state, using an IO-intensive scheduling thread in the at least one coroutine scheduling thread to schedule the coroutine corresponding to the connection request; the state between the first state and the second state is a stage between a point where the first state is about to be awakened and a point where the second state is generated; Among them, the first state is the state in which the coroutine is waiting for a data packet to execute a database command, the data packet has arrived, and the coroutine needs to be awakened; the second state is the state in which the coroutine is in a computationally intensive scheduling thread, and the coroutine initiates a specific write request for a specific file, and the coroutine scheduling thread includes the computationally intensive scheduling thread.
2. The method according to claim 1, wherein loading a dynamic library capable of replacing threads with coroutines in the operating system of the database to generate at least one coroutine scheduling thread comprises: In response to the database being unable to modify source code and not having a connection management plug-in mechanism, starting the database; Loading and initializing a dynamic runtime library to generate at least one coroutine scheduling thread, wherein the dynamic runtime library has a hook function for creating a thread, and the hook function for creating a thread is used to replace a connection processing thread generated by a native runtime library of the database with a coroutine; When the database is initialized, the hook function of the thread creation is overloaded to determine whether the currently created thread is a connection processing thread through the hook function of the thread creation. When the currently created thread is a connection processing thread, the connection processing thread is converted into a coroutine.
3. The method according to claim 1, wherein loading a dynamic library capable of replacing threads with coroutines in the operating system of the database to generate at least one coroutine scheduling thread comprises: In response to the database having a connection management plug-in mechanism, starting the database; Load and initialize the dynamic runtime library and generate at least one coroutine scheduling thread; Initializing the database; A plug-in is loaded and initialized so that the plug-in receives a connection request sent to the database, and when the thread construction request of the database is a request for processing the connection request, the plug-in controls the operation of a hook function for creating a thread in the dynamic runtime library, wherein the hook function for creating a thread is used to determine whether the currently created thread is a connection processing thread, and when the currently created thread is a connection processing thread, the connection processing thread is converted into a coroutine.
4. The method according to any one of claims 1-3, the method further comprising: Dividing the at least one coroutine scheduling thread into an IO-intensive scheduling thread and a computation-intensive scheduling thread; The step of scheduling the coroutine by the at least one coroutine scheduling thread to complete the access task corresponding to the connection request includes: Detect whether the coroutine corresponding to the connection request is in a state between the first state and the second state. If it is detected that the coroutine corresponding to the connection request is in a state between the first state and the second state, use the computationally intensive scheduling thread among the at least one coroutine scheduling thread to schedule the coroutine corresponding to the connection request.
5. The method according to claim 4, wherein, The "if it is detected that the coroutine corresponding to the connection request is not in a state between the first state and the second state, use the I / O intensive scheduling thread among the at least one coroutine scheduling thread to schedule the coroutine corresponding to the connection request" includes: In response to the coroutine corresponding to the connection request being in the stage of creating a connection, place the coroutine in the current I / O intensive scheduling thread, and the current I / O intensive scheduling thread is determined based on the load balancing algorithm; In response to the coroutine corresponding to the connection request being in a specific write operation on a specific file, and before completing the submission of the I / O request for writing the specific file and yielding the coroutine to enter I / O waiting, migrate the coroutine to the current I / O intensive scheduling thread.
6. The method according to claim 5, wherein, The database is a MySQL database. The "in response to the coroutine corresponding to the connection request being in a specific write operation on a specific file, and before completing the submission of the I / O request for writing the specific file and yielding the coroutine to enter I / O waiting, migrate the coroutine to the current I / O intensive scheduling thread" includes: In response to the coroutine corresponding to the connection request being in a write operation on the binary log file, and before completing the submission of the file I / O request and yielding the coroutine to enter I / O waiting, migrate the coroutine to the current I / O intensive scheduling thread.
7. The method according to claim 5, wherein, The method further includes: Detect whether there is a coroutine in the I / O intensive scheduling thread that drives batch submission; If there is a coroutine in the I / O intensive scheduling thread that drives batch submission, migrate the coroutine woken up by the coroutine that drives batch submission to the I / O intensive scheduling thread, and the I / O intensive scheduling thread into which the coroutine woken up by the coroutine that drives batch submission migrates is determined based on the load balancing algorithm.
8. The method according to claim 7, wherein, The database is a MySQL database with group commit enabled. The "detect whether there is a coroutine in the I / O intensive scheduling thread that drives batch submission" includes: Detect whether there is a group leader coroutine in the I / O intensive scheduling thread that drives the group commit process for writing the binary log file; The "if there is a coroutine in the I / O intensive scheduling thread that drives batch submission, migrate the coroutine woken up by the coroutine to the I / O intensive scheduling thread" includes: If it is detected that there is a group leader coroutine for writing the binary log file, migrate the member coroutines woken up by the group leader coroutine to the I / O intensive scheduling thread, and the I / O intensive scheduling thread into which each member coroutine migrates is determined based on the load balancing algorithm.
9. A database thread pool control device, the device comprising: A loading unit, configured to load a dynamic runtime library capable of replacing threads with coroutines in the operating system of the database, and generate at least one coroutine scheduling thread, where the coroutine scheduling thread is used to schedule at least one coroutine; A receiving unit, configured to receive a connection request sent by a client to the database; A detection unit configured to detect whether a request for the database to create a new thread is a request for processing the connection request; A creation unit configured to, in response to detecting that the request for the database to create a new thread is a request for processing the connection request, create a coroutine corresponding to the connection request, and schedule the coroutine through the at least one coroutine scheduling thread to complete the access task corresponding to the connection request; The creation unit is further configured to: if it is detected that the coroutine corresponding to the connection request is not in a state between a first state and a second state, use an I / O intensive scheduling thread in the at least one coroutine scheduling thread to schedule the coroutine corresponding to the connection request; the state between the first state and the second state is a stage from the point where the first state is about to be awakened to the point where the second state is generated; Wherein, the first state is the state of the coroutine waiting to execute a data packet of a database command, the data packet has arrived, and the coroutine needs to be awakened; the second state is the state of the coroutine located in a computationally intensive scheduling thread, and the coroutine initiates a specific write request for a specific file, and the coroutine scheduling thread includes the computationally intensive scheduling thread.
10. An electronic device, comprising: One or more processors; A storage device having one or more programs stored thereon; When the one or more programs are executed by the one or more processors, the one or more processors implement the method according to any one of claims 1-8.
11. A computer-readable medium, having a computer program stored thereon, wherein, When the program is executed by a processor, it implements the method according to any one of claims 1-8.
Citation Information
Patent Citations
PHP framework-based user request processing method and apparatus, and electronic device
CN112347169A
Cited By
Database thread pool control method and apparatus, electronic device, and computer medium
EP4654011A1