Replication Worker Services#
Scope#
This document describes the Replication worker services in Qserv. The worker services are responsible for processing requests that are submitted by the Replication Controller. The protocol is based on HTTP/JSON.
Categories#
There are two general categories of requests depending on the request processing mechanism.
The first group includes requests that are processed asynchronously. Once a request of this type is validated and accepted by the service, it’s put into a priority queue of the Replication worker in an order which depends on the priority level of the request and a presense of other requests in the queue. The requests also have an expiration timeout. If a request is not processed within the timeout, it will be automatically cancelled by the server. Another important attribute of the queued requests is their unique identifier. The identifier is generated by the Controller and it’s used to track the request status and to retrieve the results of the request once it’s finished. The following request types belong to this category:
Test requests (echo, etc.)
Replica management (find, create, delete replicas)
Database management (SQL) (SQL operations)
Director index data inquiries (director index data inqueries)
The second group includes requests that are processed immediately (synchronously) by the services:
Managing queued requests (inspect and manage queued requests)
Worker service management (inspect and manage the worker server)
The requests of this category are not put into the processing queue and they are not tracked by the request identifiers. However, they may refer to the queued requests by their identifiers to perform operations on them (e.g., to track the status of a queued request or to cancel a queued request).
Request identifiers#
Note
The Worker service management requests do not have identifiers.
All queued requests are required to have the unique identifiers. The identifiers are generated by the Controller and are used to track the status of the requests and to retrieve their results once they are finished. Here is how the request identifiers are used in the API:
The request identifier is a mandatory attribute of the request body for all queued requests.
The identifier is a string.
The request will not be accepted by the service if the identifier is missing or if it’s not unique (i.e., if there is already a request with the same identifier in the processing queue).
The identifiers are also reported in responses of the queued requests and in responses of the Managing queued requests services.
The request identifier is used to track the status of the request and to retrieve the results of the request once it’s finished. The tracking and retrieval operations are performed by the Managing queued requests services.
Collections of the request identifiers can be also reported by the Worker service management services.
Request parameters#
Common parameters#
Although request parameters vary by type, certain attributes are common to all requests and are included with every request type, as detailed in the following subsections. The following attributes are passed with any request type, regardless of the HTTP method:
instance_idstringThe mandatory identifier of a Qserv instance served by the Replication System.
versionnumber =0The optional version of the Qserv REST API. See Protocol Versioning for more information on the API versioning.
For the POST, PUT and DELETE request types values of the attributes are send in the request body:
{
"instance_id" : <string>,
"version" : <number>
}
For GET request types, parameters are specified in the URL query:
?instance_id=<string>&version=<number>
JSON body of the queued requests#
All requests that are queued by the worker service before processed by the service are sent with the POST method.
The request body of each such request is a JSON object that has the following schema:
{
"id" : <string>,
"timeout" : <number>,
"priority" : <number>,
"params" : {
...
}
}
Where:
idstringThe unique ID of the request (generated by the Controller).
timeoutnumber =1The optional request expiration timeout. The timeout is meant for automatic cancelation of the unfinished requests. The timeout is expressed in seconds. For requests where the timeout is not set explicitly or where its value was set to
0the worker-specific default value will be used. The default value is set in the configuration parameter (controller,request-timeout-sec) of the worker service.prioritynumberThe priority level of the request. Requests with higher priority levels are processed before the requests with lower priority levels.
paramsobjectThe object containing the request-specific attributes. The schema of this object depends on the type of the request. The payload of the object is documented in the relevant sections below.
Response objects#
All responses from the worker services have the following general schema:
{
"success" : <number>,
"error" : <string>,
"error_ext" : <object>,
"warning" : <string>,
"req" : {
"id" : <string>,
"priority" : <number>,
"timeout" : <number>
"params" : <object>,
},
"resp" : {
"status" : <string>,
"status_ext" : <string>,
"error" : <string>,
"type" : <string>,
"expiration_timeout_sec" : <number>,
"perf" : {
"finish_time" : <number>,
"receive_time" : <number>,
"start_time" : <number>
},
"result" : <object>
}
}
Where the first group of the attrubutes represent the common completion status of the request which is applicable to all REST
services in Qserv. Attributes in this groups should be considered for all request types regardless of the request processing
mechanism (synchronous or asynchronous). Normally, if a request is successfully accepted by the service then the success
attribute will be set to 1 and the error and error_ext attributes will be empty.
successnumberThe completion status of the request. The value of
1means that the request was successfully accepted by the service after evaluating the input parameters and a context of the request. The value of0indicates any problems with the operation. The error message will be provided in theerrorattribute.errorstringThe error message in case of the failed request.
error_extobjectThe extended error message in case of the failed request.
warningstringThe optional warning message that may be posted in case of the successful request.
The second group represents the original request parameters as they were received by the service. These attributes
are encapsulated into the req object in the response:
idstringThe unique ID of the request (generated by the Controller).
prioritynumberThe priority level of the request.
timeoutnumber =0The request expiration timeout that was passed in the original request. The timeout is meant for automatic cancelling/disposing requests regardless of their statuses. The timeout is expressed in seconds. For requests where the timeout is not set or where its value was set to
0the worker-specific default value will be used.paramsobjectThe original request-specific parameters as they were received by the service. The schema of this object depends on the type of the request. The payload of the object is documented in the relevant sections below.
The third group represents the completion (or the ongoing processing) status of the request and its result-specific results. These attributes
are encapsulated into the resp object in the response:
statusstringThe human readable representation of completion status of the operation. Values are defined in the C++
enumtypereplica::protocol::Status.status_extstringThe human readable representation of the extended status of this operation. Values are defined in the C++
enumtypereplica::protocol::StatusExt::Status.errorstringThe error message in case of the failed request.
typestringThe type of the request. Values are produced by the service based on the type of the request and its processing context.
expiration_timeout_secintThe effective expiration timeout of the request in seconds. This value is equal to the value of the
timeoutattribute passed in the original request if it was set to a non-zero value. Otherwise, this value is equal to the default timeout value set in a configuration of the worker service.perfobjectThe performance metrics of the request. Values of these parameters may change during request processing before the request is finished. The object has the following attributes:
receive_timeuint64_tWhen the request was received by a worker service (milliseconds since UNIX Epoch). A non-zero value is guaranteeded for all requests that were received by the worker service.
start_timeuint64_tWhen the request was started by a worker service (milliseconds since UNIX Epoch). A value of
0means that the request is still in the processing queue.finish_timeuint64_tWhen the request was finished by a worker service (milliseconds since UNIX Epoch). A value of
0means that the request is still in the processing queue or it’s still being processed.
resultobjectThe result of the request. The schema of this object depends on the type and the completion status of the request:
The object is empty for requests that were failed.
The object is empty for all newly submitted requests that ended up in the processing queue and for requests which are still being processed.
The object is filled with the relevant data for the requests that is finished or failed.
Schemas of the
resultobjects are documented in the relevant sections below.
Test requests#
Note
This group of requests belongs the queued category. Requests of this type are processed by the worker service asynchronously by a dedicated pool of the worker threads. Parameters of this request type are sent in the request body as a JSON object.
Echo#
The Controller sends a POST request to the Replication worker to test the functionality of the worker processor
and to simulate the request submission/processing path. The echo request has no persistent side effects, such
as changes to the worker databases. Parameters of the request will be evaluated by the service. If the parameters
are correct and the request looks good, then the request will be queued for processing. Otherwise, the service will
return an error.
POST /worker/echo
These are the request-specific attributes:
"params" : {
"delay" : <uint32_t>,
"data" : <string>
}
Where:
delayintThe delay in milliseconds before the request is processed.
datastringThe data to be echoed back.
The schema of the result object in the responses of the succesfully completed requests is presented below:
"result" : {
"data" : <string>
}
An example of the complete request object for the echo request that is mean to to finish in 60000 milliseconds
after its start is presented below:
{
"instance_id": "qserv_proj",
"auth_key": "replauthkey",
"id": "1234567",
"params": {
"data": "abcdefg",
"delay": 60000
}
}
The request could be sent as (required attributes instance_id and auth_key are ommited in
the request’s body for brevity):
curl 'http://sdfqserv002:25805/worker/echo?version=56' \
-X POST \
-H 'Content-Type: application/json' \
-d'{"id":"1234567","params":{"data":"abcdefg","delay":60000}}'
The response object will be:
{
"success" : 1,
"warning" : "",
"error" : "",
"error_ext" : {},
"req" : {
"id" : "1234567",
"params" : {
"data" : "abcdefg",
"delay" : 60000
},
"priority" : 0,
"timeout" : 0
},
"resp" : {
"error" : "",
"expiration_timeout_sec" : 28800,
"perf" : {
"finish_time" : 0,
"receive_time" : 1779484832104,
"start_time" : 0
},
"result" : {},
"status" : "CREATED",
"status_ext" : "NONE",
"type" : "TEST_ECHO"
}
}
Note:
The
resultobject is still empty at this point because the request is still being processed (status=CREATED).The request status is reported as
CREATEDand thestart_timeis set to0because the request is still in the processing queue and it has not been started by the worker service yet.A value of the
expiration_timeout_secis reporting the default value of the worker service because the request was submitted with a timeout value of0.
Results of the completed requests can be obtained by tracking the request with the ID 1234567 as
explained in Managing queued requests section below.
curl 'http://sdfqserv002:25805/worker/request/track/1234567?version=56&instance_id=qserv_proj' \
-X GET
Here is an example of the response object for the request tracking operation on the previously submitted request that is still in progress:
{
"success" : 1,
"warning" : "",
"error" : "",
"error_ext" : {},
"req" : {
"id" : "1234567",
"params" : {
"data" : "abcdefg",
"delay" : 60000
},
"priority" : 0,
"timeout" : 0
},
"resp" : {
"error" : "",
"expiration_timeout_sec" : 28800,
"perf" : {
"finish_time" : 0,
"receive_time" : 1779484832104,
"start_time" : 1779484832104
},
"result" : {},
"status" : "IN_PROGRESS",
"status_ext" : "NONE",
"type" : "TEST_ECHO"
}
}
Note that the result object is still empty at this point because the request is still being processed (status = IN_PROGRESS).
The request status is reported as IN_PROGRESS and the start_time
is set to the time when the request was started by the worker service.
And here is an example of the response object for the request that has been completed successfully:
{
"success" : 1,
"warning" : "",
"error" : "",
"error_ext" : {},
"req" : {
"id" : "1234567",
"params" : {
"data" : "abcdefg",
"delay" : 60000
},
"priority" : 0,
"timeout" : 0
},
"resp" : {
"error" : "",
"expiration_timeout_sec" : 28800,
"perf" : {
"finish_time" : 1779484892116,
"receive_time" : 1779484832104,
"start_time" : 1779484832104
},
"result" : {
"data" : "abcdefg"
},
"status" : "SUCCESS",
"status_ext" : "NONE",
"type" : "TEST_ECHO"
}
}
The response object contains the result of the request in the result attribute. The request status is reported
as SUCCESS and the finish_time is set to the time when the request
was finished by the worker service.
Replica management#
Note
This group of requests belongs the queued category. Requests of this type are processed by the worker service asynchronously by a dedicated pool of the worker threads. Parameters of this request type are sent in the request body as a JSON object.
Create replica#
The Controller sends a POST request to the Replication worker to initiate the replica creation operation on the target worker. The operation affects all files of the chunk’s tables in a scope of the specified database. All such files found at the source worker will be copied from the source worker to the target worker.
POST /worker/replica/create
These are the request-specific attributes:
"params" : {
"database" : <string>,
"chunk" : <uint32_t>,
"worker" : <string>,
"worker_host" : <string>,
"worker_port" : <uint16_t>
}
Where:
databasestringThe name of the database for which the replica should be created.
chunkuint32_tThe chunk number for which the replica should be created.
workerstringThe source worker ID from where to pull the replica.
worker_hoststringThe source worker host (DNS or IP).
worker_portuint16_tThe source worker port.
The request-specific attributes in the response objects will have the following values:
"type" : "REPLICATE",
"result" : <replica-info-object>
Where <replica-info-object> is the object is described in Schema of the replica info object section below.
Note that the object represent the state of the replica after the creation operation is finished. The replica may be incomplete
if some files are missing at the source worker or if some files failed to be copied to the target worker.
Delete replica#
The Controller sends a POST request to the Replication worker to initiate the replica deletion operation on the target worker. The operation affects all files of the chunk’s tables in a scope of the specified database. All such files found at the source worker will be deleted from the worker.
POST /worker/replica/delete
These are the request-specific attributes:
"params" : {
"database" : <string>,
"chunk" : <uint32_t>
}
Where:
databasestringThe name of the database for which the replica should be deleted.
chunkuint32_tThe chunk number for which the replica should be deleted.
The request-specific attributes in the response objects will have the following values:
"type" : "DELETE",
"result" : <replica-info-object>
Where <replica-info-object> is the object is described in Schema of the replica info object section below.
Note that the object represent the state of the replica after the deletion operation is finished. The replica state
is always NOT_FOUND upon the completion of the deletion operation.
Find replica#
The Controller sends a POST request to the Replication worker to initiate the replica lookup and status reporting operation on the target worker. The operation affects all files of the chunk’s tables in a scope of the specified database. All such files found at the source worker will be reported in the response.
POST /worker/replica/find
These are the request-specific attributes:
"params" : {
"database" : <string>,
"chunk" : <uint32_t>,
"compute_cs" : <int>
}
Where:
databasestringThe name of the database for which the replica should be found.
chunkuint32_tThe chunk number for which the replica should be found.
compute_csintCompute the control sum of the replica files if not
0. Note that computing control sums can be a time consuming operation.
The request-specific attributes in the response objects will have the following values:
"type" : "FIND",
"result" : <replica-info-object>
Where <replica-info-object> is the object is described in Schema of the replica info object section below.
Note that the object represent the state of the replica after the find operation is finished. The replica state
can be any of the allowed values: NOT_FOUND, CORRUPT, INCOMPLETE, and COMPLETE.
Find all replicas#
The Controller sends a POST request to the Replication worker to initiate the replica lookup and status reporting operation on the target worker. The operation affects all files of all chunk tables in a scope of the specified database. All such files found at the source worker will be reported in the response.
POST /worker/replica/find-all
These are the request-specific attributes:
"params" : {
"database" : <string>
}
Where:
databasestringThe name of the database for which the replicas should be found.
The request-specific attributes in the response objects will have the following values:
"type" : "FIND-ALL",
"result" : {
"replica_info_many" : [
<replica-info-object>,
...
]
}
Where <replica-info-object> is the object is described in Schema of the replica info object section below.
Schema of the replica info object#
All replica management operations (create, delete, find) return the same schema of the <replica-info-object>
which contains the information on the state of a replica affected by the operation. The schema of the object is presented below:
{
"replica_info" : {
"status" : <string>,
"worker" : <string>,
"database" : <string>,
"chunk" : <uint32_t>,
"verify_time" : <uint64_t>,
"files": [
{
"name" : <string>,
"size" : <uint64_t>,
"mtime" : <uint64_t>,
"cs" : <string>,
"begin_transfer_time" : <uint64_t>,
"end_transfer_time" : <uint64_t>,
"in_size" : <uint64_t>
},
...
]
}
}
Where the common attributes of the replica_info object are:
statusstringThe status of the replica. Values corresponds to the stringified values of the enum type
ReplicaInfo::Status. The allowed values are:NOT_FOUND,CORRUPT,INCOMPLETE, andCOMPLETE.workerstringThe worker ID of the worker where the replica is (was) residing (the target worker).
databasestringThe name of the database.
chunkuint32_tThe chunk number.
verify_timeuint64_tWhen the replica status was verified by a worker in milliseconds (since UNIX Epoch). A value of
0means that the replica status has not been verified by a worker yet.
And the attributes of each file in the files array are:
namestringThe short name of a file w/o the path.
sizeuint64_tThe size of the file in bytes.
mtimestd::time_tThe content modification time of the file in seconds (since UNIX Epoch).
csstringThe control sum of the file (if available).
begin_transfer_timeuint64_tWhen the file migration started (where applies) in milliseconds (since UNIX Epoch). A value of
0means that the file migration has not been started yet.end_transfer_timeuint64_tWhen the file migration finished (where applies) in milliseconds (since UNIX Epoch). A value of
0means that the file migration has not been finished yet.in_sizeuint64_tThe size of an input file (where applies) in bytes. Note that
0is a valid value for empty file. A value of0can be also reported if the file migration has not been started yet.
Database management (SQL)#
Note
This group of requests belongs the queued category. Requests of this type are processed by the worker service asynchronously by a dedicated pool of the worker threads. Parameters of this request type are sent in the request body as a JSON object.
This service is meant to execute the DDL and DML statements against the worker MariaDB database:
POST /worker/sql
These are the request-specific attributes:
"params" : {
"database" : <string>,
"sql_request_type" : <string>,
"batch_mode" : <int>,
"max_rows" : <int>,
"binary_encoding" : <string>,
..
}
Where, the mandatory attributes of the params object are:
databasestringThe name of a database defining a context in which the SQL statements should be executed. Depending on an operation, this could also be the name of a database affected by a request (e.g. the database to be created, dropped, “enabled” or “disabled”).
sql_request_typestringThe type of the SQL request. Allowed values are defined in the C++
enumtypereplica::protocol::SqlRequestType. The following SQL request types are supported by the service:QUERY, CREATE_DATABASE, DROP_DATABASE, ENABLE_DATABASE, DISABLE_DATABASE, GRANT_ACCESS, CREATE_TABLE, DROP_TABLE, REMOVE_TABLE_PARTITIONING, DROP_TABLE_PARTITION, GET_TABLE_INDEX, CREATE_TABLE_INDEX, DROP_TABLE_INDEX, ALTER_TABLE, TABLE_ROW_STATS
The operations are explained in further details in the relevant sections below.
batch_modeintThe flag indicating if the operation applies to a collection of tables whose names are provided in a request, or to a specific table. A value of
1means that the batch mode should be used. A value of0means that the non-batch mode should be used.The batch mode is only applicable to the following operations:
CREATE_TABLE, DROP_TABLE, REMOVE_TABLE_PARTITIONING, DROP_TABLE_PARTITION, GET_TABLE_INDEX, CREATE_TABLE_INDEX, DROP_TABLE_INDEX, ALTER_TABLE, TABLE_ROW_STATS
max_rowsint =0The optional parameter for the maximum number of rows to be returned in the result set. A value of
0means that there is no limit on the number of rows to be returned.Warning
For result sets exceeding the specified limit (unless
max_rowsis set to0) the service always returns an error. Setting a very high value for this parameter may lead to excessive memory consumption and performance degradation. When sending requests of the QUERY type always useLIMIT <N>where it’s possible.binary_encodingstring =hexThe optional parameter for the encoding of the data in the result set. Allowed values are
hex,b64,arrayornone. The default value ishex. More details on these options are provided in: Binary encoding of the data in JSON.
Request-specific parameters required by each operation type are documented in the relevant sections below.
The schema of the result object is the same for all operations. It contains the completion status and
serialized MySQL result sets for each scope (the name of a database, the name of a table, etc.) and
is presented below:
"type" : "SQL_<sql-request-type>",
"result" : [
{
"scope" : <string>,
"result_set" : {
"status_ext" : <int>,
"status_ext_str" : <string>,
"error" : <string>,
"char_set_name" : <string>,
"has_result": <int>,
"fields" : [
{
"name" : <string>,
"org_name" : <string>,
"table" : <string>,
"org_table" : <string>,
"db" : <string>,
"catalog" : <string>,
"def" : <string>,
"length" : <int>,
"max_length" : <int>,
"flags" : <int>,
"decimals" : <int>,
"type" : <int>
},
...
],
"rows" : [
{
"cells" : [
<encoded-cell-value>, ...
],
"nulls" : [
<int>, ...
]
},
...
]
},
...
]
Where:
typestringThe type name is a concatenation of the
SQL_prefix followed by the request type (e.g.,SQL_QUERY,SQL_CREATE_TABLE, etc.).scopestringThe scope of the result set (e.g., the name of a database, the name of a table, etc.).
status_extintExtended status of this operation. Values are defined in the C++
enumtypereplica::protocol::StatusExt::Status.status_ext_strstringThe human readable representation of the above-defined completion status of the operation.
errorstringThe error message if the operation failed.
char_set_namestringThe name of the character set used in the result set.
has_resultintWhether the result set contains any rows (i.e., whether the result set is empty or not). Values are
0or1.fieldsRepresents column definitions (see MySQL C API), in which each entry has the following attributes:
namestringThe name of the field, as a null-terminated string. If the field was given an alias with an AS clause, the value of name is the alias. For a procedure parameter, the parameter nameThe name of the field.
org_namestringThe name of the field, as a null-terminated string. Aliases are ignored. For expressions, the value is an empty string. For a procedure parameter, the parameter name.
tablestringThe name of the table containing this field, if it is not a calculated field. For calculated fields, the table value is an empty string. If the column is selected from a view, table names the view. If the table or view was given an alias with an AS clause, the value of table is the alias. For a UNION, the value is the empty string. For a procedure parameter, the procedure name.
org_tablestringThe name of the table, as a null-terminated string. Aliases are ignored. If the column is selected from a view,
org_tablenames the view. If the column is selected from a derived table, org_table names the base table. If a derived table wraps a view,org_tablestill names the base table. If the column is an expression, org_table is the empty string. For a UNION, the value is the empty string. For a procedure parameter, the value is the procedure name.dbstringThe name of the database that the field comes from, as a null-terminated string. If the field is a calculated field,
dbis an empty string. For a UNION, the value is the empty string. For a procedure parameter, the name of the database containing the procedure.catalogstringThe catalog name. This value is always “def”.
defstringThe default value of this field, as a null-terminated string. This is set only if you use
mysql_list_fields().lengthuint32_tThe width of the field. This corresponds to the display length, in bytes.
The server determines the
lengthvalue before it generates the result set, so this is the minimum length required for a data type capable of holding the largest possible value from the result column, without knowing in advance the actual values that will be produced by the query for the result set.For string columns, the
lengthvalue varies on the connection character set. For example, if the character set islatin1, a single-byte character set, thelengthvalue for a SELECT ‘abc’ query is 3. If the character set isutf8mb4, a multibyte character set in which characters take up to 4 bytes, thelengthvalue is 12.max_lengthuint32_tThe maximum width of the field for the result set (the length in bytes of the longest field value for the rows actually in the result set). The value of
max_lengthis the length of the string representation of the values in the result set.flagsuint32_tThe flags associated with the field (e.g., whether it’s a primary key, whether it’s nullable, etc.). Further details on allowed flag values can be found in MySQL C API.
decimalsuint32_tThe number of decimals for numeric fields, and the fractional seconds precision for temporal fields.
typeenum_field_types (MySQL C type)The numeric data type of the field (e.g.,
MYSQL_TYPE_TINY,MYSQL_TYPE_SHORT, etc.). Further details on allowed type values can be found in MySQL C API.
rowsRepresents rows of the result set, in which each row is an array of string values corresponding to the fields defined in the
fieldsarray.Each value in the collection is an object that has two arrays:
cellsarray of stringThe array of the binary values corresponding to the fields defined in the
fieldsarray. Each value is encoded into a string as per the specified encoding scheme. It’s up to the client to decode the values and to convert them to the appropriate data types based on the information provided in thefieldsarray.nullsarray of intThe array of flags indicating whether the corresponding value in the
cellsarray is NULL (1) or not (0).
Examples of the request and response objects for specific operations are provided in the relevant sections below.
QUERY#
Execute an arbitrary SQL query against the worker database.
These are the request-specific attributes:
"params" : {
"sql_request_type" : "QUERY",
"query" : <string>
}
Where:
querystringThe SQL query to be executed.
CREATE_DATABASE#
Create a new database at the worker.
These are the request-specific attributes:
"params" : {
"sql_request_type" : "CREATE_DATABASE",
"if_not_exists" : <int>
}
Where:
if_not_existsint =1The optional flag specifying whether the database should be created only if it does not exist. Values are
0or1. Note that the default value is1which means that an attempt to create the database will be made only if it does not exist. If the value is set to0and the database already exists then the operation will fail and a error will be returned.
DROP_DATABASE#
Drop a database from the worker.
These are the request-specific attributes:
"params" : {
"sql_request_type" : "DROP_DATABASE",
"if_exists" : <int>
}
Where:
if_existsint =1The optional flag specifying whether the database should be dropped only if it exists. Values are
0or1. Note that the default value is1which means that an attempt to drop the database will be made only if it exists. If the value is set to0and the database does not exist then the operation will fail and a error will be returned.
ENABLE_DATABASE#
Enable (i.e., make it available for processing user queries) a database by registering it at
the metadata table qservw_worker.Dbs.
These are the request-specific attributes:
"params" : {
"sql_request_type" : "ENABLE_DATABASE"
}
DISABLE_DATABASE#
Disable (i.e., make it unavailable for processing user queries) a database at the worker by removing it from
the metadata table qservw_worker.Dbs and removing all chunk entries from the metadata table qservw_worker.Chunks.
These are the request-specific attributes:
"params" : {
"sql_request_type" : "DISABLE_DATABASE"
}
GRANT_ACCESS#
Grant access to a database for a specific user.
These are the request-specific attributes:
"params" : {
"sql_request_type" : "GRANT_ACCESS",
"user" : <string>,
"host" : <string>
}
Where:
userstringThe name of the user to which access should be granted (e.g.,
qsmaster). The parameter is used for the GRANT_ACCESS operation only.hoststringThe host from which the user can connect to the database (e.g.,
%for any host,localhostand/or127.0.0.1for local connections only, etc.). The parameter is used for the GRANT_ACCESS operation only.
CREATE_TABLE#
Create a new table (or many tables) in the database. If MySQL partitioning was requested for the table then configure partitioning parameters and add the initial partition corresponding to the default transaction identifier. The table will be partitioned based on values of the transaction identifiers in the specified column.
These are the request-specific attributes in the batch mode ("batch_mode" : 1):
"params" : {
"sql_request_type" : "CREATE_TABLE",
"tables": [<string>, ...],
"engine" : <string>,
"comment" : <string>,
"charset_name" : <string>,
"collation_name" : <string>,
"columns" : [
{"name" : <string>, "type" : <string>},
...
],
"partition_by_column" : <string>,
"if_not_exists" : <int>
}
The attributes for the single-table mode ("batch_mode" : 0) are the same as for the batch mode except that the table
attribute is mandatory and the tables attribute is not applicable:
"params" : {
"sql_request_type" : "CREATE_TABLE",
"table" : <string>,
"engine" : <string>,
"comment" : <string>,
"charset_name" : <string>,
"collation_name" : <string>,
"columns" : [
{"name" : <string>, "type" : <string>},
...
],
"partition_by_column" : <string>,
"if_not_exists" : <int>
}
Where:
tablesarray of stringThe list of table names to which the operation should be applied.
tablestringThe name of the table to which the operation should be applied.
enginestringThe name of the storage engine to be used for the table (e.g.,
MyISAM).commentstringThe comment to be added to the table.
charset_namestringThe name of the character set to be used for the table (e.g.,
utf8mb4).collation_namestringThe name of the collation to be used for the table (e.g.,
utf8mb4_general_ci).columnsarray of objectThe list of column definitions. Each column definition is an object with the following attributes:
namestringThe name of the column.
typestringThe data type of the column (e.g.,
INT,VARCHAR(255), etc.).
partition_by_columnstringThe name of the column by which the table should be partitioned (e.g.,
qserv_trans_id).Note
Although the attribute
partition_by_columnis always required for this type of request, its value is allowed to be empty. If it’s empty, then the table will be created without partitioning. This rule applies to both batch and single-table modes.if_not_existsint =1The optional flag specifying whether the table should be created only if it does not exist. Values are
0or1. Note that the default value is1which means that an attempt to create the table will be made only if it does not exist. If the value is set to0and the table already exists then the operation will fail and a error will be returned.
DROP_TABLE#
Drop a table (or many tables) from the database.
These are the request-specific attributes in the batch mode ("batch_mode" : 1):
"params" : {
"sql_request_type" : "DROP_TABLE",
"tables": [<string>, ...],
"if_exists" : <int>
}
The attributes for the single-table mode ("batch_mode" : 0) are the same as for the batch mode except that the table
attribute is mandatory and the tables attribute is not applicable:
"params" : {
"sql_request_type" : "DROP_TABLE",
"table" : <string>,
"if_exists" : <int>
}
Where:
tablesarray of stringThe list of table names to which the operation should be applied.
tablestringThe name of the table to which the operation should be applied.
if_existsint =1The optional flag specifying whether the table should be dropped only if it exists. Values are
0or1. Note that the default value is1which means that an attempt to drop the table will be made only if it exists. If the value is set to0and the table does not exist then the operation will fail and a error will be returned.
REMOVE_TABLE_PARTITIONING#
Remove partitioning from a table (or from many tables). This operation will convert the table into the non-partitioned table by merging all partitions into a single table. The partitioning parameters will be removed from the table definition.
These are the request-specific attributes in the batch mode ("batch_mode" : 1):
"params" : {
"sql_request_type" : "REMOVE_TABLE_PARTITIONING",
"tables": [<string>, ...]
}
The attributes for the single-table mode ("batch_mode" : 0) are the same as for the batch mode except that the table
attribute is mandatory and the tables attribute is not applicable:
"params" : {
"sql_request_type" : "REMOVE_TABLE_PARTITIONING",
"table" : <string>
}
Where:
tablesarray of stringThe list of table names to which the operation should be applied.
tablestringThe name of the table to which the operation should be applied.
DROP_TABLE_PARTITION#
Drop a partition corresponding to the specified transaction identifier (transaction_id) from a table (or from many tables).
These are the request-specific attributes in the batch mode ("batch_mode" : 1):
"params" : {
"sql_request_type" : "DROP_TABLE_PARTITION",
"tables": [<string>, ...],
"transaction_id" : <uint32_t>,
"if_exists" : <int>
}
The attributes for the single-table mode ("batch_mode" : 0) are the same as for the batch mode except that the table
attribute is mandatory and the tables attribute is not applicable:
"params" : {
"sql_request_type" : "DROP_TABLE_PARTITION",
"table" : <string>,
"transaction_id" : <uint32_t>,
"if_exists" : <int>
}
Where:
tablesarray of stringThe list of table names to which the operation should be applied.
tablestringThe name of the table to which the operation should be applied.
transaction_iduint32_tThe transaction ID for operations that should be executed within a transaction.
if_existsint =1The optional flag specifying whether the partition should be dropped only if it exists. Values are
0or1. Note that the default value is1which means that an attempt to drop the partition will be made only if it exists. If the value is set to0and the partition does not exist then the operation will fail and a error will be returned.
GET_TABLE_INDEX#
Retrieve the index information for a table (or for many tables).
These are the request-specific attributes in the batch mode ("batch_mode" : 1):
"params" : {
"sql_request_type" : "GET_TABLE_INDEX",
"tables": [<string>, ...]
}
The attributes for the single-table mode ("batch_mode" : 0) are the same as for the batch mode except that the table
attribute is mandatory and the tables attribute is not applicable:
"params" : {
"sql_request_type" : "GET_TABLE_INDEX",
"table" : <string>
}
Where:
tablesarray of stringThe list of table names to which the operation should be applied.
tablestringThe name of the table to which the operation should be applied.
CREATE_TABLE_INDEX#
Create an index for a table (or for many tables).
These are the request-specific attributes in the batch mode ("batch_mode" : 1):
"params" : {
"sql_request_type" : "CREATE_TABLE_INDEX",
"tables": [<string>, ...],
"index" : <object>,
"if_not_exists" : <int>
}
The attributes for the single-table mode ("batch_mode" : 0) are the same as for the batch mode except that the table
attribute is mandatory and the tables attribute is not applicable:
"params" : {
"sql_request_type" : "CREATE_TABLE_INDEX",
"table" : <string>,
"index" : <object>,
"if_not_exists"
}
Where:
tablesarray of stringThe list of table names to which the operation should be applied.
tablestringThe name of the table to which the operation should be applied.
indexobjectThe specification of the index to be created. The schema of the object is documented in the section Creating (Data table indeces) of the Qserv Administrator’s Guide.
if_not_existsint =1The optional flag specifying whether the index should be created only if it does not exist. Values are
0or1. Note that the default value is1which means that an attempt to create the index will be made only if it does not exist. If the value is set to0and the index already exists then the operation will fail and a error will be returned.
DROP_TABLE_INDEX#
Drop an index from a table (or for many tables).
These are the request-specific attributes in the batch mode ("batch_mode" : 1):
"params" : {
"sql_request_type" : "DROP_TABLE_INDEX",
"tables": [<string>, ...],
"index_name" : <string>,
"if_exists" : <int>
}
The attributes for the single-table mode ("batch_mode" : 0) are the same as for the batch mode except that the table
attribute is mandatory and the tables attribute is not applicable:
"params" : {
"sql_request_type" : "DROP_TABLE_INDEX",
"table" : <string>,
"index_name" : <string>,
"if_exists" : <int>
}
Where:
tablesarray of stringThe list of table names to which the operation should be applied.
tablestringThe name of the table to which the operation should be applied.
index_namestringThe name of the index to be dropped.
if_existsint =1The optional flag specifying whether the index should be dropped only if it exists. Values are
0or1. Note that the default value is1which means that an attempt to drop the index will be made only if it exists. If the value is set to0and the index does not exist then the operation will fail and a error will be returned.
ALTER_TABLE#
Alter the structure of a table (or for many tables).
These are the request-specific attributes in the batch mode ("batch_mode" : 1):
"params" : {
"sql_request_type" : "ALTER_TABLE",
"tables": [<string>, ...],
"alter_spec" : <string>
}
The attributes for the single-table mode ("batch_mode" : 0) are the same as for the batch mode except that the table
attribute is mandatory and the tables attribute is not applicable:
"params" : {
"sql_request_type" : "ALTER_TABLE",
"table" : <string>,
"alter_spec" : <string>
}
Where:
tablesarray of stringThe list of table names to which the operation should be applied.
tablestringThe name of the table to which the operation should be applied.
Where:
alter_specstringThe specification for the ALTER TABLE operation (e.g.,
ADD COLUMN col1 INT,DROP COLUMN col1, etc.). See MySQL documentation on theALTER TABLEstatement for more details on the syntax of thealter_specstring.
TABLE_ROW_STATS#
Retrieve row statistics for a table (or for many tables). The service will count rows in the table and report the number of rows in the result.
These are the request-specific attributes in the batch mode ("batch_mode" : 1):
"params" : {
"sql_request_type" : "TABLE_ROW_STATS",
"tables": [<string>, ...]
}
The attributes for the single-table mode ("batch_mode" : 0) are the same as for the batch mode except that the table
attribute is mandatory and the tables attribute is not applicable:
"params" : {
"sql_request_type" : "TABLE_ROW_STATS",
"table" : <string>
}
Where:
tablesarray of stringThe list of table names to which the operation should be applied.
tablestringThe name of the table to which the operation should be applied.
Director index data inquiries#
The API for pulling data for constructing the director index tables is provided by a group of the following services:
The services are designed to be used by the Controller in the following steps:
Ask a worker to extract the data for the specified chunk of the director table from MySQL. The result will be written into a temporary CSV-formatted file at the worker. The URL of this file will be returned in the response object.
Pull the CSV file from the worker node into a location from which the Controller will push the data into the director index table.
Tell the worker to clean up the CSV file.
These operations can be (and should be) performed in parallel for many chunks. The Controller is responsible for orchestrating the operations and for ensuring that the data are pulled for all chunks of the chunk table.
Extracting the index data from MySQL into the CSV file#
Note
This request belongs the queued category. Requests of this type are processed by the worker service asynchronously by a dedicated pool of the worker threads. Parameters of this request type are sent in the request body as a JSON object.
This service is meant to pull data for constructing the director index tables. The service scans the specified chunk table
and, depending on a value of the parameter has_transaction returns either a quadruplet of the form
(<trans-id>, <director-key-id>, <chunk-id>, <sub-chunk-id>) or a triplet of the form
(<director-key-id>, <chunk-id>, <sub-chunk-id>) for each row of the chunk table.
The data are CSV-formatted. The following CSV dialect is used:
The field delimiter is a tab character (
'\t').The string values are not quoted.
The line terminator is a newline character (
'\n').
The service path is as follows:
POST /worker/director-index
These are the request-specific attributes:
"params" : {
"database" : <string>,
"director_table" : <string>,
"has_transaction" : <int>,
"transaction_id" : <uint64_t>
"chunk" : <uint32_t>
}
Where:
databasestringThe name of the database to which the chunk table belongs.
director_tablestringThe name of the director table for which the index data should be pulled. Note that the name should not have the chunk number. It has to be exactly the same as the name of the director table as it’s presented to the Qserv users, e.g.
Object, etc.has_transactionintWhether the chunk table has a transaction column (i.e., whether the chunk table is partitioned by transaction identifiers). Values are
0or1.transaction_iduint64_tThe transaction identifier for which the data should be pulled. This parameter is only applicable if
has_transactionis1.chunkuint32_tThe chunk number for which the data should be pulled.
The request-specific schema of the response object is presented below:
"type" : "INDEX",
"result" : {
"url" : <string>,
"total_bytes" : <uint64_t>
}
Where:
urlstringThe URL of the temporary file containing the CSV-formatted data pulled from the chunk table.
total_bytesuint64_tThe total number of bytes in the temporary file containing the data pulled from the chunk table.
Example of the extraction request and response#
An example of a request to get the index data for chunk number 70781 of the director table Source is as follows:
cat request.json
{
"instance_id":"",
"auth_key":"",
"id":"12345678951",
"params":{
"database":"dp1",
"director_table":"Source",
"has_transaction":0,
"transaction_id":0,
"chunk":70781
}
}
curl 'http://sdfqserv002:25805/worker/director-index?version=56' \
-X POST \
-H 'Content-Type: application/json' \
-d@request.json
Once the request finishes processing at the worker node, the response will have the following format:
{
"success" : 1,
"warning" : "",
"error" : "",
"error_ext" : {},
"req" : {
"id" : "12345678951",
"params" : {
"chunk" : 70781,
"database" : "dp1",
"director_table" : "Source",
"has_transaction" : 0,
"transaction_id" : 0
},
"priority" : 0,
"timeout" : 0
},
"resp" : {
"status" : "SUCCESS",
"status_ext" : "NONE",
"error" : "",
"type" : "INDEX",
"expiration_timeout_sec" : 28800,
"perf" : {
"receive_time" : 1780532948215,
"start_time" : 1780532948216,
"finish_time" : 1780532950047
},
"result" : {
"size_bytes" : 57817898,
"url" : "http://sdfqserv002.sdf.slac.stanford.edu:25805/worker/director-index-data/dp1-Source/70781-12345678951.csv"
}
}
}
Pulling the index data from the CSV file#
Note
This request belongs the synchronous category. Requests of this type are processed by the worker service instanteniously.
Tip
The service is documented here for the sake of completeness. The Controller is supposed to pull the CSV files from the worker nodes by sending a GET request for the exact file URL returned by the Extracting the index data from MySQL into the CSV file service.
The CSV files are pulled from the worker nodes by the Controller using:
GET /worker/director-index/:folder/:file
Where:
folderstringThe relative path of the folder containing the temporary file with the CSV-formatted data pulled from the chunk table. The relative folder path is extracted from the URL returned by the Extracting the index data from MySQL into the CSV file service.
filestringThe name of the temporary file containing the CSV-formatted data pulled from the chunk table. The file name is extracted from the URL returned by the Extracting the index data from MySQL into the CSV file service.
Requests of this type do not have a body.
Example of pulling the index data from the CSV file#
An example of a request to pull the CSV file created by the Example of the extraction request and response service for chunk
number 70781 of the director table Source is as follows:
curl 'http://sdfqserv002:25805/worker/director-index/dp1-Source/70781-12345678951.csv' \
-X GET \
-o 70781-12345678951.csv
Cleaning up the temporary files#
Note
This request belongs the synchronous category. Requests of this type are processed by the worker service instanteniously.
Tip
The service is documented here for the sake of completeness. The Controller is supposed to remove the CSV files from the worker nodes by sending a DELETE request for the exact file URL returned by the Extracting the index data from MySQL into the CSV file service.
Tip
It’s recommended to clean up the temporary files explicitly as soon as they are no longer needed (i.e., as soon as the data are pulled from the worker node) in order to free up disk space at the worker nodes. Note that the temporary files are also automatically removed by the worker service when the service starts up.
The CSV files are deleted by sending requests to the following service:
DELETE /worker/director-index/:folder/:file
Where:
folderstringThe relative path of the folder containing the temporary file with the CSV-formatted data pulled from the chunk table. The relative folder path is extracted from the URL returned by the Extracting the index data from MySQL into the CSV file service.
filestringThe name of the temporary file containing the CSV-formatted data pulled from the chunk table. The file name is extracted from the URL returned by the Extracting the index data from MySQL into the CSV file service.
The body of a request is required to have parameters explained in sections:
Example of cleaning up the temporary CSV file#
An example of a request to delete the CSV file created by the Example of the extraction request and response service for chunk
number 70781 of the director table Source is as follows:
curl 'http://sdfqserv002:25805/worker/director-index/dp1-Source/70781-12345678951.csv' \
-X DELETE \
-H 'Content-Type: application/json' \
-d '{"instance_id":"","auth_key":""}'
Managing queued requests#
Note
This group of the synchronous requests are meant to monitor and manage the corresponding queued requests (the “target” requests). Requests of this type are processed by the worker service instanteniously. Depending on the HTTP method, parameters of this request type are sent either in in the request body as a JSON object or in the query string of the request URL.
The request management requests do not have their own identity.
Track a request#
The Controller sends a GET request to the Replication worker to track the status of a previously submitted request. The “tracking” operation combines the status retrieval and the result retrieval operations. If the request is still in the processing queue or if it’s still being processed, then the response will contain the current status of the request and an empty result object. Once the request is finished, the response will contain the final status of the request and the result of the request.
The tracking requests do not change the state of the tracked request.
GET /worker/replica/track/:id
Where:
idstringThe unique ID of the request to be tracked.
The request-specific attributes in the response objects depend on the type of the tracked request. For example, if the tracked request is a Find all replicas request, then the request-specific attributes in the response object will have the following values:
"type" : "FIND-ALL",
"result" : {
"replica_info_many" : [
<replica-info-object>,
...
]
}
Hence in order to correctly interpret the request-specific attributes in the response object, the client code should either rely on the “type” attribute in the response object or ensure that the type of the tracked request is already known for the request’s identifier.
Tip
The request tracking operation can return the large payload in the response object (e.g., for the Find all replicas request). Hence, it is recommended to use this operation only when necessary to obtain the status and the result of a specific request. In case if the status of the target request is all that is needed the client should consider using the Retrieve the status of a request service.
Retrieve the status of a request#
The Controller sends a GET request to the Replication worker to retrieve the status of a previously submitted request. The request status is reported in
the status and status_str attributes of the response object. The request management requests do not change the state of the tracked request.
GET /worker/replica/status/:id
Where:
idstringThe unique ID of the request for which the status should be retrieved.
The request-specific attributes in the response objects depend on the type of the target request. For example, if the target request is a Find all replicas request, then the request-specific attributes in the response object will have the following values:
"type" : "FIND-ALL",
"result" : {}
Note that the result object is empty in this case because the request tracking operation is not performed by this service. To get the result
of the request, the client should use the Track a request service.
Stop a request#
The Controller sends a PUT request to the Replication worker to stop the previously made request. The “stop” operation is meant to stop the target request regardless of the current state of the request. If the request is still in the processing queue, then the request will be removed from the processing queue and it will not be processed by the worker. If the request is already being processed by the worker, then the worker will try to stop the processing of the request as soon as possible. If the request is already finished, then the “stop” operation will not have any effect on the request.
PUT /worker/request/stop/:id
Where:
idstringThe unique ID of the request to be stopped.
The request-specific attributes in the response objects depend on the type of the target request. For example, if the target request is a Find all replicas request, then the request-specific attributes in the response object will have the following values:
"type" : "FIND-ALL",
"result" : {}
Note that the result object is empty in this case because the request tracking operation is not performed by this service. To get the result
of the request, the client should use the Track a request service.
Dispose completed requests#
Warning
The response schema of this request type differs from the response schema of other request management services. See details below.
The Controller sends a PUT request to the Replication worker to dispose the completed requests from the worker’s internal storage. The “dispose” operation is meant to free up the resources occupied by the completed requests in the worker service. The disposed requests will not be available for tracking or status retrieval operations anymore.
PUT /worker/request/dispose
Where the request object is required to provide a collection (array) of the request IDs to be disposed:
{
"params" : {
"ids" : [
<string>,
...
<string>
]
}
}
The response object will have the general completion status of the operation and flags indicating an effect of the operation on each identifier mentioned in the request:
{
"status" : 1,
"status_str" : "SUCCESS",
"status_ext" : 0,
"status_ext_str" : "NONE",
"ids_disposed" : [
{
"id" : <string>,
"disposed" : <int>
},
...
]
}
Where the value of the integer in the disposed attribute is the completion status of the operation for the corresponding request ID.
The value of 1 means that the request was disposed successfully. The value of 0 means that the request was not found.
Note that the completion status of this operation is alwasy SUCCESS if the request object is correct
and the operation was performed.
Worker service management#
Note
This group of the synchronous requests is meant to monitor and manage the worker server itself. Requests of this type are processed by the worker service instanteniously.
The request-specific attributes are not defined for these requests.
Responses returned by the services report the status of the worker request processor itself. The result object has the following attributes:
"result" : {
"service_state" : <string>,
"num_new_requests" : <int>,
"num_in_progress_requests" : <int>,
"num_finished_requests" : <int>,
"new_requests" : [
...
],
"in_progress_requests" : [
...
],
"finished_requests" : [
...
]
}
Where:
service_statestringThe human readable representation of current state of the worker request processor. Values are defined in the C++
enumtypereplica::protocol::ServiceState. The allowed values are:SUSPEND_IN_PROGRESS,SUSPENDED,RUNNING.num_new_requestsintThe number of requests in the processing queue that have not been started by the worker service yet.
num_in_progress_requestsintThe number of requests that are currently being processed by the worker service.
num_finished_requestsintThe number of requests that were finished by the worker service during a certain time period (e.g., since the last restart).
new_requestsarrayAn array of objects representing requests that are in the processing queue but have not been started by the worker service yet.
in_progress_requestsarrayAn array of objects representing requests that are currently being processed by the worker service.
finished_requestsarrayAn array of objects representing requests that were finished by the worker service during a certain time period (e.g., since the last restart).
Note
The new_requests, in_progress_requests, and finished_requests arrays are populated only for specific request types.
These collections will not be empty only for the following request types:
The schema of the request descriptors in the collections is presented below:
{
"req" : <object>,
"resp" : <object>,
}
See the section Response objects for further details on the attributes req and resp.
Get the worker status#
The Controller sends a GET request to the Replication worker to get the status of the worker service:
GET /worker/service/status
Get info on requests at various stages of processing#
The Controller sends a GET request to the Replication worker to get the information on the requests:
GET /worker/service/requests
The response object of this request will have the new_requests, in_progress_requests, and finished_requests arrays populated with
status descriptors of the corresponding requests. The request descriptors have the same schema as the original request objects.
Suspend the worker service#
The Controller sends a PUT request to the Replication worker to suspend processing queued requests by the worker service. All ongoing requests will be told to stop as soon as possible. No requests will be taken from the processing queue for processing until the worker service is resumed. The new requests will be still accepted and put in the processing queue but they will not be processed until the worker service is resumed. The finished requests are not affected by this operation.
PUT /worker/service/suspend
Note
Upon the completion of this operation the worker service will be put in the SUSPEND_IN_PROGRESS state
before it is put in the SUSPENDED state. The intermediate state of SUSPEND_IN_PROGRESS means that
the service is still in the process of stopping the ongoing requests and it is not yet fully suspended.
The service will be in the SUSPENDED state when all ongoing requests are stopped and no new requests are being processed.
Resume the worker service#
The Controller sends a PUT request to the Replication worker to resume processing queued requests
by the worker service. The worker service will be put in the RUNNING state and it will start taking requests from
the processing queue for processing. The new requests will be still accepted and put in the processing queue as well.
The finished requests are not affected by this operation.
PUT /worker/service/resume
Drain requests at the worker service#
The Controller sends a PUT request to the Replication worker to drain (stop) all requests in the worker service. The operation affects requests that are already in the processing queue or requests that are still in the input queue waiting to be procesed. The finished requests are not affected by this operation.
PUT /worker/service/drain
The response object of this request will have the new_requests, in_progress_requests, and finished_requests arrays populated with
status descriptors of the corresponding requests. The request descriptors have the same schema as the original request objects.
Reconfigure the worker service#
The Controller sends a PUT request to the Replication worker to reconfigure the worker service. This operation forced the worker service to re-read info on the database families, databases and tables from the Replication System’s database and update the worker’s internal state (cache) accordingly. Normally this operaton is triggered after the changes are made to the database families, databases and tables managed by the Replication System to make sure that the worker service has the up-to-date information on these entities.
PUT /worker/service/reconfig