Entorno de configuración
Gitalb 14.9
está construido por docker, y la base de datos utilizada es el postgresql incorporado
fondo del problema
Recientemente, descubrí que cuando el sistema de desarrollo propio solicita llamar a la interfaz api de gitlab, especialmente cuando se solicita el mismo recurso al mismo tiempo , estoy creando el recurso del subgrupo al mismo tiempo aquí , y obtendré un error de 500. Al principio Pensé que era el código del sistema desarrollado por mí mismo. El error 500 causado por datos inexactos no está demasiado preocupado. Pero este fenómeno ha reaparecido recientemente, así que intente verificar la causa del error.
Simule el entorno generador de errores
Luego realice una prueba de estrés para verificar si realmente es un problema causado por llamadas simultáneas. Primero intente iniciar 5 subprocesos al mismo tiempo dentro de 0.01 segundos para solicitar la creación de recursos de subgrupos
Este error se reprodujo directamente bajo una pequeña cantidad de concurrencia. Se puede ver que solo la primera solicitud devolvió el resultado normalmente, y las 4 solicitudes restantes informaron 500 Error interno
Encuentre la causa del error
error propio del sistema
El registro nginx de gitlab, que se encuentra en /var/log/gitlab/nginx/gitlab_access.log, indica que esta solicitud se devolvió 500
Hay un módulo gitlab-rails en gitlab, y
la causa del error se encontró en el archivo de registro api_json.log debajo de este módulo.
{
"time": "2023-07-19T05:19:06.173Z",
"severity": "INFO",
"duration_s": 0.08902,
"db_duration_s": 0.0557,
"view_duration_s": 0.03332,
"status": 500,
"method": "POST",
"path": "/api/v4/groups",
"params": [{
"key": "path",
"value": "gcptest071902"
}, {
"key": "name",
"value": "gcptest071902"
}, {
"key": "parent_id",
"value": 234
}],
"host": "wx8vm00001.apac.bosch.com",
"remote_ip": "10.4.103.206, 127.0.0.1",
"ua": "python-requests/2.28.1",
"route": "/api/:version/groups",
"user_id": 1,
"username": "root",
"exception.class": "ActiveRecord::RecordNotUnique",
"exception.message": "PG::UniqueViolation: ERROR: duplicate key value violates unique constraint \"index_namespaces_name_parent_id_type\"\nDETAIL: Key (name, parent_id, type)=(gcptest071902, 234, Group) already exists.\n",
"exception.backtrace": ["lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer'", "lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write'", "lib/gitlab/database/load_balancing/load_balancer.rb:172:in `retry_with_backoff'", "lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write'", "lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer'", "lib/gitlab/database/load_balancing/connection_proxy.rb:67:in `block (2 levels) in <class:ConnectionProxy>'", "lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer'", "lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write'", "lib/gitlab/database/load_balancing/load_balancer.rb:172:in `retry_with_backoff'", "lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write'", "lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer'", "lib/gitlab/database/load_balancing/connection_proxy.rb:77:in `transaction'", "app/services/groups/create_service.rb:39:in `block in execute'", "lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer'", "lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write'", "lib/gitlab/database/load_balancing/load_balancer.rb:172:in `retry_with_backoff'", "lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write'", "lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer'", "lib/gitlab/database/load_balancing/connection_proxy.rb:77:in `transaction'", "lib/gitlab/database.rb:309:in `block in transaction'", "lib/gitlab/database.rb:308:in `transaction'", "app/models/concerns/cross_database_modification.rb:99:in `transaction'", "app/services/groups/create_service.rb:38:in `execute'", "lib/api/groups.rb:63:in `create_group'", "lib/api/groups.rb:207:in `block (2 levels) in <class:Groups>'", "lib/api/api_guard.rb:213:in `call'", "lib/gitlab/metrics/elasticsearch_rack_middleware.rb:16:in `call'", "lib/gitlab/middleware/rails_queue_duration.rb:33:in `call'", "lib/gitlab/middleware/memory_report.rb:13:in `call'", "lib/gitlab/middleware/speedscope.rb:13:in `call'", "lib/gitlab/request_profiler/middleware.rb:17:in `call'", "lib/gitlab/database/load_balancing/rack_middleware.rb:23:in `call'", "lib/gitlab/metrics/rack_middleware.rb:16:in `block in call'", "lib/gitlab/metrics/web_transaction.rb:46:in `run'", "lib/gitlab/metrics/rack_middleware.rb:16:in `call'", "lib/gitlab/jira/middleware.rb:19:in `call'", "lib/gitlab/middleware/go.rb:20:in `call'", "lib/gitlab/etag_caching/middleware.rb:21:in `call'", "lib/gitlab/middleware/query_analyzer.rb:11:in `block in call'", "lib/gitlab/database/query_analyzer.rb:46:in `within'", "lib/gitlab/middleware/query_analyzer.rb:11:in `call'", "lib/gitlab/middleware/multipart.rb:173:in `call'", "lib/gitlab/middleware/read_only/controller.rb:50:in `call'", "lib/gitlab/middleware/read_only.rb:18:in `call'", "lib/gitlab/middleware/same_site_cookies.rb:27:in `call'", "lib/gitlab/middleware/handle_malformed_strings.rb:21:in `call'", "lib/gitlab/middleware/basic_health_check.rb:25:in `call'", "lib/gitlab/middleware/handle_ip_spoof_attack_error.rb:25:in `call'", "lib/gitlab/middleware/request_context.rb:21:in `call'", "lib/gitlab/middleware/webhook_recursion_detection.rb:15:in `call'", "config/initializers/fix_local_cache_middleware.rb:11:in `call'", "lib/gitlab/middleware/compressed_json.rb:26:in `call'", "lib/gitlab/middleware/rack_multipart_tempfile_factory.rb:19:in `call'", "lib/gitlab/middleware/sidekiq_web_static.rb:20:in `call'", "lib/gitlab/metrics/requests_rack_middleware.rb:77:in `call'", "lib/gitlab/middleware/release_env.rb:13:in `call'"],
"exception.sql": "/*application:web,correlation_id:01H5P9CWAR3B4123CHYQSZKYH5,endpoint_id:POST /api/:version/groups,db_config_name:main*/ INSERT INTO \"namespaces\" (\"name\", \"path\", \"created_at\", \"updated_at\", \"type\", \"visibility_level\", \"description_html\", \"parent_id\", \"cached_markdown_version\") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING \"id\"",
"queue_duration_s": 0.009978,
"redis_calls": 5,
"redis_duration_s": 0.001121,
"redis_read_bytes": 609,
"redis_write_bytes": 304,
"redis_cache_calls": 3,
"redis_cache_duration_s": 0.000656,
"redis_cache_read_bytes": 609,
"redis_cache_write_bytes": 198,
"redis_shared_state_calls": 2,
"redis_shared_state_duration_s": 0.000465,
"redis_shared_state_write_bytes": 106,
"db_count": 15,
"db_write_count": 3,
"db_cached_count": 0,
"db_replica_count": 0,
"db_primary_count": 15,
"db_main_count": 15,
"db_main_replica_count": 0,
"db_replica_cached_count": 0,
"db_primary_cached_count": 0,
"db_main_cached_count": 0,
"db_main_replica_cached_count": 0,
"db_replica_wal_count": 0,
"db_primary_wal_count": 0,
"db_main_wal_count": 0,
"db_main_replica_wal_count": 0,
"db_replica_wal_cached_count": 0,
"db_primary_wal_cached_count": 0,
"db_main_wal_cached_count": 0,
"db_main_replica_wal_cached_count": 0,
"db_replica_duration_s": 0.0,
"db_primary_duration_s": 0.056,
"db_main_duration_s": 0.056,
"db_main_replica_duration_s": 0.0,
"cpu_s": 0.043004,
"mem_objects": 15895,
"mem_bytes": 1253816,
"mem_mallocs": 4559,
"mem_total_bytes": 1889616,
"pid": 413885,
"correlation_id": "01H5P9CWAR3B4123CHYQSZKYH5",
"meta.user": "root",
"meta.client_id": "user/1",
"meta.caller_id": "POST /api/:version/groups",
"meta.remote_ip": "10.4.103.206",
"meta.feature_category": "subgroups",
"content_length": "68",
"request_urgency": "default",
"target_duration_s": 1
}
Al mismo tiempo, este error también se puede encontrar en el archivo de registroExceptions_json.log en este módulo.
{
"severity": "ERROR",
"time": "2023-07-19T05:19:06.171Z",
"correlation_id": "01H5P9CWAR3B4123CHYQSZKYH5",
"exception.class": "ActiveRecord::RecordNotUnique",
"exception.message": "PG::UniqueViolation: ERROR: duplicate key value violates unique constraint \"index_namespaces_name_parent_id_type\"\nDETAIL: Key (name, parent_id, type)=(gcptest071902, 234, Group) already exists.\n",
"exception.backtrace": ["lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer'", "lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write'", "lib/gitlab/database/load_balancing/load_balancer.rb:172:in `retry_with_backoff'", "lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write'", "lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer'", "lib/gitlab/database/load_balancing/connection_proxy.rb:67:in `block (2 levels) in \u003cclass:ConnectionProxy\u003e'", "lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer'", "lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write'", "lib/gitlab/database/load_balancing/load_balancer.rb:172:in `retry_with_backoff'", "lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write'", "lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer'", "lib/gitlab/database/load_balancing/connection_proxy.rb:77:in `transaction'", "app/services/groups/create_service.rb:39:in `block in execute'", "lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer'", "lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write'", "lib/gitlab/database/load_balancing/load_balancer.rb:172:in `retry_with_backoff'", "lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write'", "lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer'", "lib/gitlab/database/load_balancing/connection_proxy.rb:77:in `transaction'", "lib/gitlab/database.rb:309:in `block in transaction'", "lib/gitlab/database.rb:308:in `transaction'", "app/models/concerns/cross_database_modification.rb:99:in `transaction'", "app/services/groups/create_service.rb:38:in `execute'", "lib/api/groups.rb:63:in `create_group'", "lib/api/groups.rb:207:in `block (2 levels) in \u003cclass:Groups\u003e'", "lib/api/api_guard.rb:213:in `call'", "lib/gitlab/metrics/elasticsearch_rack_middleware.rb:16:in `call'", "lib/gitlab/middleware/rails_queue_duration.rb:33:in `call'", "lib/gitlab/middleware/memory_report.rb:13:in `call'", "lib/gitlab/middleware/speedscope.rb:13:in `call'", "lib/gitlab/request_profiler/middleware.rb:17:in `call'", "lib/gitlab/database/load_balancing/rack_middleware.rb:23:in `call'", "lib/gitlab/metrics/rack_middleware.rb:16:in `block in call'", "lib/gitlab/metrics/web_transaction.rb:46:in `run'", "lib/gitlab/metrics/rack_middleware.rb:16:in `call'", "lib/gitlab/jira/middleware.rb:19:in `call'", "lib/gitlab/middleware/go.rb:20:in `call'", "lib/gitlab/etag_caching/middleware.rb:21:in `call'", "lib/gitlab/middleware/query_analyzer.rb:11:in `block in call'", "lib/gitlab/database/query_analyzer.rb:46:in `within'", "lib/gitlab/middleware/query_analyzer.rb:11:in `call'", "lib/gitlab/middleware/multipart.rb:173:in `call'", "lib/gitlab/middleware/read_only/controller.rb:50:in `call'", "lib/gitlab/middleware/read_only.rb:18:in `call'", "lib/gitlab/middleware/same_site_cookies.rb:27:in `call'", "lib/gitlab/middleware/handle_malformed_strings.rb:21:in `call'", "lib/gitlab/middleware/basic_health_check.rb:25:in `call'", "lib/gitlab/middleware/handle_ip_spoof_attack_error.rb:25:in `call'", "lib/gitlab/middleware/request_context.rb:21:in `call'", "lib/gitlab/middleware/webhook_recursion_detection.rb:15:in `call'", "config/initializers/fix_local_cache_middleware.rb:11:in `call'", "lib/gitlab/middleware/compressed_json.rb:26:in `call'", "lib/gitlab/middleware/rack_multipart_tempfile_factory.rb:19:in `call'", "lib/gitlab/middleware/sidekiq_web_static.rb:20:in `call'", "lib/gitlab/metrics/requests_rack_middleware.rb:77:in `call'", "lib/gitlab/middleware/release_env.rb:13:in `call'"],
"exception.sql": "/*application:web,correlation_id:01H5P9CWAR3B4123CHYQSZKYH5,endpoint_id:POST /api/:version/groups,db_config_name:main*/ INSERT INTO \"namespaces\" (\"name\", \"path\", \"created_at\", \"updated_at\", \"type\", \"visibility_level\", \"description_html\", \"parent_id\", \"cached_markdown_version\") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING \"id\"",
"user.username": "root",
"tags.program": "web",
"tags.locale": "en",
"tags.feature_category": "subgroups",
"tags.correlation_id": "01H5P9CWAR3B4123CHYQSZKYH5"
}
analisis inicial
El mensaje de error está relacionado con el problema de equilibrio de carga de la base de datos de GitLab. El equilibrio de carga de la base de datos en GitLab está diseñado para manejar la alta disponibilidad y el rendimiento de las conexiones de la base de datos. Sin embargo, al usar el balanceo de carga, a veces puede encontrarse con problemas que provocan que la conexión de la base de datos falle con este error.
Parece que también hay problemas con las transacciones de la base de datos de GitLab en los registros. La transacción es un mecanismo utilizado para garantizar la atomicidad, consistencia, aislamiento y durabilidad de las operaciones de la base de datos. En GitLab, las transacciones de la base de datos se utilizan para garantizar la coherencia y la integridad de los datos.
Este error generalmente puede ser causado por:
-
Problema de conexión de la base de datos: puede haber un problema con la conexión de la base de datos, lo que hace que GitLab no pueda conectarse a la base de datos normalmente. Esto podría deberse a una falla del servidor de la base de datos, problemas de red o una mala configuración.
-
Bloqueo de la base de datos: si varias transacciones operan en el mismo recurso de la base de datos al mismo tiempo y se produce una competencia de bloqueo, es posible que una de las transacciones falle.
-
Interbloqueo de la base de datos: si varias transacciones esperan entre sí para liberar el bloqueo y forman una espera circular, se produce un interbloqueo de la base de datos, lo que hace que una de las transacciones falle.
-
Tiempo de espera de la transacción: si el tiempo de ejecución de la transacción es demasiado largo y excede el período de tiempo de espera de la transacción establecido por la base de datos, la transacción puede fallar.
Soluciones posibles:
-
Use una base de datos externa, ajuste la configuración relevante de la transacción de la base de datos
-
Verifique el estado y el rendimiento del servidor de la base de datos para asegurarse de que el servidor de la base de datos esté activo y funcione correctamente.
-
Verifique la configuración y los ajustes de la conexión de la base de datos para asegurarse de que el servidor de GitLab pueda conectarse correctamente a la base de datos.
-
Verifique y optimice los índices de la base de datos y las declaraciones de consulta para reducir la posibilidad de bloqueos e interbloqueos de la base de datos.
-
Ajuste la configuración de transacciones de la base de datos, como aumentar los tiempos de espera de las transacciones, para adaptarse a tiempos de procesamiento de transacciones más prolongados.
-
Verifique los registros en el servidor de la base de datos y el servidor de GitLab para ver si hay otros mensajes de error que puedan causar que la transacción falle.
El análisis anterior es más probable que no podamos involucrar cambios, y no estamos seguros de si este problema se ha solucionado en la nueva versión de gitlab. Puede intentar actualizar la versión de gitlab para ver si se puede resolver, o agregar un bloqueo global a la capa empresarial o arquitectura distribuida para prohibir solicitudes concurrentes simultáneas para operar el mismo recurso en el nivel de milisegundos, lo que debería resolver este problema.