Uploaded image for project: 'MariaDB Connector/C'
  1. MariaDB Connector/C
  2. CONC-277

"Plugin pvio_socket could not be loaded: not initialized" error when starting akonadi

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • None
    • None
    • None
    • None
    • mariadb 10.2.8

    Description

      When starting akonadi against a mariadb 10.2 database, the startup fails.

      Database error: Cannot open database.
        Last driver error: "QMYSQL: Unable to connect"
        Last database error: "Plugin pvio_socket could not be loaded: not initialized"
      Unable to open database "Plugin pvio_socket could not be loaded: not initialized QMYSQL: Unable to connect"
      "[
      0: akonadiserver(_Z11akBacktracev+0x39) [0x46bd59]
      1: akonadiserver() [0x46c056]
      2: /lib64/libc.so.6(+0x36d10) [0x7fe6633b1d10]
      3: /lib64/libc.so.6(gsignal+0x9f) [0x7fe6633b1c9f]
      4: /lib64/libc.so.6(abort+0x1a7) [0x7fe6633b3717]
      5: /usr/lib64/qt/lib/libQtCore.so.4(_Z17qt_message_output9QtMsgTypePKc+0x70) [0x7fe664fd4d90]
      6: akonadiserver(_ZN15FileDebugStream9writeDataEPKcx+0xa3) [0x46e423]
      7: /usr/lib64/qt/lib/libQtCore.so.4(_ZN9QIODevice5writeEPKcx+0x159) [0x7fe665070459]
      8: /usr/lib64/qt/lib/libQtCore.so.4(+0x129360) [0x7fe66507d360]
      9: /usr/lib64/qt/lib/libQtCore.so.4(_ZN11QTextStreamD2Ev+0x31) [0x7fe665085e31]
      10: akonadiserver(_ZN7Akonadi6Server13AkonadiServer4initEv+0xbda) [0x47230a]
      11: akonadiserver() [0x559e49]
      12: /usr/lib64/qt/lib/libQtCore.so.4(_ZN7QObject5eventEP6QEvent+0x1b1) [0x7fe6650fae61]
      13: /usr/lib64/qt/lib/libQtCore.so.4(_ZN16QCoreApplication14notifyInternalEP7QObjectP6QEvent+0x6e) [0x7fe6650e1ffe]
      14: /usr/lib64/qt/lib/libQtCore.so.4(_ZN23QCoreApplicationPrivate16sendPostedEventsEP7QObjectiP11QThreadData+0x2e2) [0x7fe6650e4e92]
      15: /usr/lib64/qt/lib/libQtCore.so.4(+0x1bc16e) [0x7fe66511016e]
      16: /usr/lib64/libglib-2.0.so.0(g_main_context_dispatch+0x2c7) [0x7fe6628771a7]
      17: /usr/lib64/libglib-2.0.so.0(+0x493b8) [0x7fe6628773b8]
      18: /usr/lib64/libglib-2.0.so.0(g_main_context_iteration+0x2c) [0x7fe66287743c]
      19: /usr/lib64/qt/lib/libQtCore.so.4(_ZN20QEventDispatcherGlib13processEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE+0x76) [0x7fe6651102d6]
      20: /usr/lib64/qt/lib/libQtCore.so.4(_ZN10QEventLoop13processEventsE6QFlagsINS_17ProcessEventsFlagEE+0x34) [0x7fe6650e06e4]
      21: /usr/lib64/qt/lib/libQtCore.so.4(_ZN10QEventLoop4execE6QFlagsINS_17ProcessEventsFlagEE+0x196) [0x7fe6650e09f6]
      22: /usr/lib64/qt/lib/libQtCore.so.4(_ZN16QCoreApplication4execEv+0x8c) [0x7fe6650e608c]
      23: akonadiserver(main+0x1ec) [0x463e3c]
      24: /lib64/libc.so.6(__libc_start_main+0xea) [0x7fe66339c02a]
      25: akonadiserver(_start+0x2a) [0x4646aa]
      ]
      "
      

      The odd thing here is that this does not happen on the first connection.
      Akonadi on startup connects once to the database to make sure it's there, it's the right version, and all the tables it needs are present. Then it disconnects again. It later reconnects with actual "worker" connections. The initial connection works, it's the later "worker" connections that fail with above error.

      Checking debugging output from akonadi one can clearly see that:

      bash-4.4$ akonadictl start
      Starting Akonadi Server...
         done.
      bash-4.4$ Connecting to deprecated signal QDBusConnectionInterface::serviceOwnerChanged(QString,QString,QString)
      search paths:  ("/usr/libexec/icecc/bin", "/usr/local/bin", "/usr/bin", "/bin", "/usr/games", "/usr/lib64/kde4/libexec", "/usr/lib64/qt/bin", "/usr/share/texmf/bin", "/usr/sbin", "/usr/local/sbin", "/usr/local/libexec", "/usr/libexec", "/opt/mysql/libexec", "/opt/local/lib/mysql5/bin", "/opt/mysql/sbin")
      Found mysql_install_db:  "/usr/bin/mysql_install_db"
      Found mysqlcheck:  "/usr/bin/mysqlcheck"
      akonadi.collectionattributetable                   OK
      akonadi.collectionmimetyperelation                 OK
      akonadi.collectionpimitemrelation                  OK
      akonadi.collectiontable                            OK
      akonadi.flagtable                                  OK
      akonadi.mimetypetable                              OK
      akonadi.parttable                                  OK
      akonadi.parttypetable                              OK
      akonadi.pimitemflagrelation                        OK
      akonadi.pimitemtable                               OK
      akonadi.pimitemtagrelation                         OK
      akonadi.resourcetable                              OK
      akonadi.schemaversiontable                         OK
      akonadi.tagattributetable                          OK
      akonadi.tagremoteidresourcerelationtable           OK
      akonadi.tagtable                                   OK
      akonadi.tagtypetable                               OK
      MySQL version OK (required "5.1" , available "10.2" )
      Database error: Cannot open database.
      Last driver error: "QMYSQL: Unable to connect"
      Last database error: "Plugin pvio_socket could not be loaded: not initialized"
      QSqlQuery::exec: database not open
      Unable to open database "Plugin pvio_socket could not be loaded: not initialized QMYSQL: Unable to connect"
      

      Also notable is that if one prevents akonadi from closing the initial connection (by commenting the appropriate line in the code), future "worker" connection attempts succeed.

      This behavior is the same with the Qt4 and Qt5 versions of akonadi. Considering this I'm rather tempted to see a bug in the connector rather than akonadi or Qt, especially since none of this happens with libmysqlclient.

      Attachments

        Activity

          georg Georg Richter added a comment -

          Hi Heinz,

          thank you for your bug report!

          "not initialized" in subsequent connection means, that the plugin system was not initialized via mysql_server_init before.

          Hard to analyze without code, but this can happen under the following conditions:

          a) Threaded application. Main thread is opening first connection, closes it and calls mysql_server_end (which deinitializes the plugin system). Other threads are not able anymore to load a plugin, since the plugin system was deinitialized.

          b) The MySQL structure wasn't allocated or initialized by mysql_init() call

          c) (very unlikely) the global variable which indicates if the plugin system was initialized was overwritten.

          If you can tell me where I can find the relevant code (or even better would be remote access for debugging) I will do some more investigations.

          georg Georg Richter added a comment - Hi Heinz, thank you for your bug report! "not initialized" in subsequent connection means, that the plugin system was not initialized via mysql_server_init before. Hard to analyze without code, but this can happen under the following conditions: a) Threaded application. Main thread is opening first connection, closes it and calls mysql_server_end (which deinitializes the plugin system). Other threads are not able anymore to load a plugin, since the plugin system was deinitialized. b) The MySQL structure wasn't allocated or initialized by mysql_init() call c) (very unlikely) the global variable which indicates if the plugin system was initialized was overwritten. If you can tell me where I can find the relevant code (or even better would be remote access for debugging) I will do some more investigations.
          pprkut Heinz Wiesinger added a comment - - edited

          Hi Georg,

          Thank you for the pointers!

          Akonadi is essentially a desktop application, shouldn't be too hard for you to get a local version to test against. All you need is a KDE environment.
          As for the code, akonadi uses Qt's MySQL connection driver. The relevant code for that can be found here:
          https://github.com/qt/qt/blob/v4.8.7/src/sql (for Qt4)
          https://github.com/qt/qtbase/tree/5.9/src/sql (for Qt5)

          The problem is caused by akonadi calling QSqlDatabase::removeDatabase, or at least not calling it works around it. This delete s the driver instance. My C++ is unfortunately rather basic, so I'm not entirely sure what this calls, but if this triggers the destructor of QMYSQLDriver, and the connection count drops to 0, it would call qLibraryEnd. MYSQL_VERSION_ID for MariaDB 10.2.8 should be 100208 if I understood correctly. That should make it call mysql_library_end(), rather than mysql_server_end().

          pprkut Heinz Wiesinger added a comment - - edited Hi Georg, Thank you for the pointers! Akonadi is essentially a desktop application, shouldn't be too hard for you to get a local version to test against. All you need is a KDE environment. As for the code, akonadi uses Qt's MySQL connection driver. The relevant code for that can be found here: https://github.com/qt/qt/blob/v4.8.7/src/sql (for Qt4) https://github.com/qt/qtbase/tree/5.9/src/sql (for Qt5) The problem is caused by akonadi calling QSqlDatabase::removeDatabase , or at least not calling it works around it. This delete s the driver instance. My C++ is unfortunately rather basic, so I'm not entirely sure what this calls, but if this triggers the destructor of QMYSQLDriver , and the connection count drops to 0, it would call qLibraryEnd . MYSQL_VERSION_ID for MariaDB 10.2.8 should be 100208 if I understood correctly. That should make it call mysql_library_end() , rather than mysql_server_end() .
          georg Georg Richter added a comment - - edited

          Hi,

          that makes no difference, since mysql_library_end is just a define:

          ./include/mysql.h:
          #define mysql_library_end mysql_server_end
          

          However calling any api function after mysql_library_end/mysql_server_end may end up in an error or an unexpected result, since all subsystems are deinitialized and freed (prepared statement subsystem, client plugin handler, sigpipe handler, tls/ssl driver, etc.).

          The problem is that every close of a connection calls mysql_library_end instead of doing that if the application terminates. This works in libmysql, since rather calls to mysql_init will initialize the subsystems again (which is a waste of resources) - unfortunately not in MariaDB Connector/C, which uses pthread_once for library initialization, so further calls to mysql_init or mysql_server_start have no effect.

          georg Georg Richter added a comment - - edited Hi, that makes no difference, since mysql_library_end is just a define: ./include/mysql.h: #define mysql_library_end mysql_server_end However calling any api function after mysql_library_end/mysql_server_end may end up in an error or an unexpected result, since all subsystems are deinitialized and freed (prepared statement subsystem, client plugin handler, sigpipe handler, tls/ssl driver, etc.). The problem is that every close of a connection calls mysql_library_end instead of doing that if the application terminates. This works in libmysql, since rather calls to mysql_init will initialize the subsystems again (which is a waste of resources) - unfortunately not in MariaDB Connector/C, which uses pthread_once for library initialization, so further calls to mysql_init or mysql_server_start have no effect.

          Hi Georg,

          In older versions of the library calling mysql_library_init() after calling mysql_library_end() would re-initialise the library.

          This behaviour is very useful because it enables you to create a dynamically "unload/reloadable" library or extension that includes the MariaDB library.

          If I create an extension that includes the MariaDB library, and the extension is unloaded and reloaded, then I have no idea what will happen if I cannot cleanup the MariaDB library resources, and then re-initialise them when the extension is loaded again.

          It also enables you to create a library that does not necessarily get a shutdown call when the application shuts down. Sometimes you have to write to an extension API which does not provide such a call.

          Of course, the easy way to get around this is to just not call mysql_library_end() at all. But why proved the mysql_library_end() function if there is no need to call it?

          Anyway, bottom line is, I believe it should be possible to shutdown, and startup the MariaDB library multiple times, as it was in earlier versions.

          Paul McCullagh Paul McCullagh added a comment - Hi Georg, In older versions of the library calling mysql_library_init() after calling mysql_library_end() would re-initialise the library. This behaviour is very useful because it enables you to create a dynamically "unload/reloadable" library or extension that includes the MariaDB library. If I create an extension that includes the MariaDB library, and the extension is unloaded and reloaded, then I have no idea what will happen if I cannot cleanup the MariaDB library resources, and then re-initialise them when the extension is loaded again. It also enables you to create a library that does not necessarily get a shutdown call when the application shuts down. Sometimes you have to write to an extension API which does not provide such a call. Of course, the easy way to get around this is to just not call mysql_library_end() at all. But why proved the mysql_library_end() function if there is no need to call it? Anyway, bottom line is, I believe it should be possible to shutdown, and startup the MariaDB library multiple times, as it was in earlier versions.

          People

            georg Georg Richter
            pprkut Heinz Wiesinger
            Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.