}
       }
    }
+   db_check_backend_thread_safe();
    Dmsg0(100, "db_open first time\n");
    mdb = (B_DB *)malloc(sizeof(B_DB));
    memset(mdb, 0, sizeof(B_DB));
    V(mutex);
 }
 
+void db_check_backend_thread_safe()
+{
+#ifdef HAVE_BATCH_FILE_INSERT
+   if (!mysql_thread_safe()) {
+      Emsg0(M_ABORT, 0, _("MySQL client library must be thread-safe "
+                          "when using BatchMode.\n"));
+   }
+#endif
+}
+
 /*
  * This call is needed because the message channel thread
  *  opens a database on behalf of a jcr that was created in
 
    V(mutex);
 }
 
+void db_check_backend_thread_safe()
+{
+#ifdef HAVE_BATCH_FILE_INSERT
+   if (!PQisthreadsafe()) {
+      Emsg0(M_ABORT, 0, _("Pg client library must be thread-safe "
+                          "when using BatchMode.\n"));
+   }
+#endif
+}
+
 void db_thread_cleanup()
 { }
 
 
 void db_thread_cleanup();
 void db_debug_print(JCR *jcr, FILE *fp);
 int db_int_handler(void *ctx, int num_fields, char **row);
+void db_check_backend_thread_safe();
 
 /* sql_create.c */
 int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
 
    V(mutex);
 }
 
+void db_check_backend_thread_safe()
+{
+#ifdef HAVE_BATCH_FILE_INSERT
+   if (!sqlite3_threadsafe()) {
+      Emsg0(M_ABORT, 0, _("SQLite3 client library must be thread-safe "
+                          "when using BatchMode.\n"));
+   }
+#endif
+}
+
 void db_thread_cleanup()
 {
 #ifdef HAVE_SQLITE3
 
 "       -d <nn>         set debug level to <nn>\n"
 "       -dt             print a timestamp in debug output\n"
 "       -f              fix inconsistencies\n"
+"       -t              test if client library is thread-safe\n"
 "       -v              verbose\n"
 "       -?              print this message\n\n");
    exit(1);
    int ch;
    const char *user, *password, *db_name, *dbhost;
    int dbport = 0;
+   bool test_thread=false;
    bool print_catalog=false;
    char *configfile = NULL;
    char *catalogname = NULL;
    memset(&id_list, 0, sizeof(id_list));
    memset(&name_list, 0, sizeof(name_list));
 
-   while ((ch = getopt(argc, argv, "bc:C:d:fvB?")) != -1) {
+   while ((ch = getopt(argc, argv, "bc:C:d:fvBt?")) != -1) {
       switch (ch) {
       case 'B':
          print_catalog = true;     /* get catalog information from config */
       case 'v':
          verbose++;
          break;
+      case 't':
+         test_thread=true;
+         break;
 
       case '?':
       default:
 
    OSDependentInit();
 
+   if (test_thread) {
+      /* When we will load the SQL backend with ldopen, this check would be
+       * moved after the database initialization. It will need a valid config
+       * file.
+       */
+      db_check_backend_thread_safe();
+      Pmsg0(0, _("OK - DB backend seems to be thread-safe.\n"));
+      exit(0);
+   }
+
    if (configfile) {
       CAT *catalog = NULL;
       int found = 0;