NDB API multithreading issue

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

NDB API multithreading issue

Miljen Mikić
Hi,

 

I have tried to use NDB API directly in order to obtain better performance,
and results are tremendous. Thumbs up!

 

However, I have faced an interesting issue that happens only on Windows,
while on Linux everything works just fine. It is a simple C++ application
where I perform initialization in one thread, and read data in another. In
other words, if I do everything in a single thread - it works. The error I
get is  "write access violation _my_thread_var(...) returned nullptr". The
application references "ndbclient_static.lib" and "mysqlclient.lib" from the
/lib folder of MySQL Cluster installation.

 

Any help is highly appreciated!

 

Code sample (basically followed your instructions from the official
documentation, https://dev.mysql.com/doc/ndbapi/en/ndb-examples.html):

 

Ndb_cluster_connection* init(char* connection_string) {

 

    ndb_init();

 

    // Object representing the cluster

    Ndb_cluster_connection* cluster_connection = new
Ndb_cluster_connection(connection_string);

 

    if (cluster_connection->connect(3, 2, 1)) {

        std::cout << "Cluster management server was not ready within 30
secs,error:" << cluster_connection->get_latest_error_msg() << "\n";

        exit(-1);

    }

    if (cluster_connection->wait_until_ready(10, 0) < 0) {

        std::cout << "Cluster not ready within 10 secs, error:" <<
cluster_connection->get_latest_error_msg() << std::endl;

    }

 

    return cluster_connection;

}

 

char** read(Ndb_cluster_connection* cluster_connection) {
    int count = 10000;
    char** ret_val = new char*[count];
    Ndb* ndb_obj = new Ndb(cluster_connection, "my_database_name");
    if(ndb_obj->init()) {
        APIERROR(ndb_obj->getNdbError());
    }
 
    NdbRecAttr **attr = new NdbRecAttr*[count];
 
    const NdbDictionary::Dictionary* dict = ndb_obj->getDictionary();
    const NdbDictionary::Table *table = dict->getTable("my_table_name"); <--
THIS IS THE LINE THAT THROWS ACCESS VIOLATION EXCEPTION
    ..
}

 

Best regards,

 

Miljen Mikic

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: NDB API multithreading issue

Mauritz Sundell
Hi Miljen

On 2016-04-13 15:16, Miljen Mikić wrote:

> Hi,
>
>  
>
> I have tried to use NDB API directly in order to obtain better performance,
> and results are tremendous. Thumbs up!
>
>  
>
> However, I have faced an interesting issue that happens only on Windows,
> while on Linux everything works just fine. It is a simple C++ application
> where I perform initialization in one thread, and read data in another. In
A bit unclear what you do in different threads, but ndb_init() must be
called once before any other ndb function, and preferable before any
threads using ndb are created.
If you call ndb_init() from one thread and have other threads running
you need to handle the waiting and memory synchronization between the
threads yourself.

So make sure that ndb_init() is called once before any other threads are
created.

Regards,
Mauritz Sundell

> other words, if I do everything in a single thread - it works. The error I
> get is  "write access violation _my_thread_var(...) returned nullptr". The
> application references "ndbclient_static.lib" and "mysqlclient.lib" from the
> /lib folder of MySQL Cluster installation.
>
>  
>
> Any help is highly appreciated!
>
>  
>
> Code sample (basically followed your instructions from the official
> documentation, https://dev.mysql.com/doc/ndbapi/en/ndb-examples.html):
>
>  
>
> Ndb_cluster_connection* init(char* connection_string) {
>
>  
>
>      ndb_init();
>
>  
>
>      // Object representing the cluster
>
>      Ndb_cluster_connection* cluster_connection = new
> Ndb_cluster_connection(connection_string);
>
>  
>
>      if (cluster_connection->connect(3, 2, 1)) {
>
>          std::cout << "Cluster management server was not ready within 30
> secs,error:" << cluster_connection->get_latest_error_msg() << "\n";
>
>          exit(-1);
>
>      }
>
>      if (cluster_connection->wait_until_ready(10, 0) < 0) {
>
>          std::cout << "Cluster not ready within 10 secs, error:" <<
> cluster_connection->get_latest_error_msg() << std::endl;
>
>      }
>
>  
>
>      return cluster_connection;
>
> }
>
>  
>
> char** read(Ndb_cluster_connection* cluster_connection) {
>      int count = 10000;
>      char** ret_val = new char*[count];
>      Ndb* ndb_obj = new Ndb(cluster_connection, "my_database_name");
>      if(ndb_obj->init()) {
>          APIERROR(ndb_obj->getNdbError());
>      }
>  
>      NdbRecAttr **attr = new NdbRecAttr*[count];
>  
>      const NdbDictionary::Dictionary* dict = ndb_obj->getDictionary();
>      const NdbDictionary::Table *table = dict->getTable("my_table_name"); <--
> THIS IS THE LINE THAT THROWS ACCESS VIOLATION EXCEPTION
>      ..
> }
>
>  
>
> Best regards,
>
>  
>
> Miljen Mikic
>
>


--
MySQL Cluster Mailing List
For list archives: http://lists.mysql.com/cluster
To unsubscribe:    http://lists.mysql.com/cluster

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: NDB API multithreading issue

Miljen Mikić
Hi Mauritz,

many thanks for the response. Let me try to explain a bit further. These NDB
calls are part of a larger project where I have one main, init thread that
is responsible for initialization of resources, obtaining handles etc. This
is the place where I put ndb_init() and other code needed for obtaining
Ndb_cluster_connection object. On the other hand, there is a thread (let's
call it worker thread) that runs only when there are some records that
should be written into database through NDB API. It is extremely important
that this thread runs fast and that is why I've chosen NDB API. However, if
I obtain Ndb_cluster_connection every time when this thread runs, then there
is no performance benefit because that is a part that is slow. Therefore, my
intention is to reuse Ndb_cluster_connection that I got in init thread. This
works perfectly on Linux, and throws exception on Windows.

Now when I (hopefully) explained my setup better, where should I put
ndb_init()? It is currently in a main (init) thread, and that does not work.
I cannot put it in a worker thread because in that case it will be invoked
every time when it runs, i.e. multiple times but it needs to be invoked only
once - before I obtain Ndb_cluster_connection.

Best regards,
Miljen Mikic

-----Original Message-----
From: Mauritz Sundell [mailto:[hidden email]]
Sent: Thursday, April 14, 2016 2:53 PM
To: Miljen Mikić <[hidden email]>; [hidden email]
Subject: Re: NDB API multithreading issue

Hi Miljen

On 2016-04-13 15:16, Miljen Mikić wrote:

> Hi,
>
>  
>
> I have tried to use NDB API directly in order to obtain better
> performance, and results are tremendous. Thumbs up!
>
>  
>
> However, I have faced an interesting issue that happens only on
> Windows, while on Linux everything works just fine. It is a simple C++
> application where I perform initialization in one thread, and read
> data in another. In
A bit unclear what you do in different threads, but ndb_init() must be
called once before any other ndb function, and preferable before any threads
using ndb are created.
If you call ndb_init() from one thread and have other threads running you
need to handle the waiting and memory synchronization between the threads
yourself.

So make sure that ndb_init() is called once before any other threads are
created.

Regards,
Mauritz Sundell

> other words, if I do everything in a single thread - it works. The
> error I get is  "write access violation _my_thread_var(...) returned
> nullptr". The application references "ndbclient_static.lib" and
> "mysqlclient.lib" from the /lib folder of MySQL Cluster installation.
>
>  
>
> Any help is highly appreciated!
>
>  
>
> Code sample (basically followed your instructions from the official
> documentation, https://dev.mysql.com/doc/ndbapi/en/ndb-examples.html):
>
>  
>
> Ndb_cluster_connection* init(char* connection_string) {
>
>  
>
>      ndb_init();
>
>  
>
>      // Object representing the cluster
>
>      Ndb_cluster_connection* cluster_connection = new
> Ndb_cluster_connection(connection_string);
>
>  
>
>      if (cluster_connection->connect(3, 2, 1)) {
>
>          std::cout << "Cluster management server was not ready within
> 30 secs,error:" << cluster_connection->get_latest_error_msg() << "\n";
>
>          exit(-1);
>
>      }
>
>      if (cluster_connection->wait_until_ready(10, 0) < 0) {
>
>          std::cout << "Cluster not ready within 10 secs, error:" <<
> cluster_connection->get_latest_error_msg() << std::endl;
>
>      }
>
>  
>
>      return cluster_connection;
>
> }
>
>  
>
> char** read(Ndb_cluster_connection* cluster_connection) {
>      int count = 10000;
>      char** ret_val = new char*[count];
>      Ndb* ndb_obj = new Ndb(cluster_connection, "my_database_name");
>      if(ndb_obj->init()) {
>          APIERROR(ndb_obj->getNdbError());
>      }
>  
>      NdbRecAttr **attr = new NdbRecAttr*[count];
>  
>      const NdbDictionary::Dictionary* dict = ndb_obj->getDictionary();
>      const NdbDictionary::Table *table =
> dict->getTable("my_table_name"); <-- THIS IS THE LINE THAT THROWS ACCESS
VIOLATION EXCEPTION

>      ..
> }
>
>  
>
> Best regards,
>
>  
>
> Miljen Mikic
>
>


--
MySQL Cluster Mailing List
For list archives: http://lists.mysql.com/cluster
To unsubscribe:    http://lists.mysql.com/cluster



--
MySQL Cluster Mailing List
For list archives: http://lists.mysql.com/cluster
To unsubscribe:    http://lists.mysql.com/cluster

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: NDB API multithreading issue

Mauritz Sundell
Hi Miljen

First, you should file a bug for your issue, including small test
program, at https://bugs.mysql.com/report.php.
Please do that even if we succeed to find a work around for you in these
mails.

Here are a few things you can try:

1) move call to ndb_init() in a thread that lives for the whole time you
use ndb in your application, and put a ndb_end() prior that threads end.
Make sure that the ndb_init call finished and synchronized before any
other call to ndb functions or mysql_thread_init.
This is merely making the code look nice and symmetric.

2) in your init thread add calls to mysql_thread_init() in beginning and
mysql_thread_end() prior threads end.
This since I suspect that there actually are such requirement, but that
is not documented to my knowledge.
Most application I seen calls ndb_init, creates Ndb_cluster_connection
objects, and Ndb objects in same thread, or as for the ndbcluster
storage engine in threads that have called mysql_thread_init.

If the above do not work, try move all creation of
Ndb_cluster_connection objects and Ndb objects to the same thread as
ndb_init, and then use the Ndb objects in worker threads.

Regards,
Mauritz

On 2016-04-14 15:29, Miljen Mikić wrote:

> Hi Mauritz,
>
> many thanks for the response. Let me try to explain a bit further. These NDB
> calls are part of a larger project where I have one main, init thread that
> is responsible for initialization of resources, obtaining handles etc. This
> is the place where I put ndb_init() and other code needed for obtaining
> Ndb_cluster_connection object. On the other hand, there is a thread (let's
> call it worker thread) that runs only when there are some records that
> should be written into database through NDB API. It is extremely important
> that this thread runs fast and that is why I've chosen NDB API. However, if
> I obtain Ndb_cluster_connection every time when this thread runs, then there
> is no performance benefit because that is a part that is slow. Therefore, my
> intention is to reuse Ndb_cluster_connection that I got in init thread. This
> works perfectly on Linux, and throws exception on Windows.
>
> Now when I (hopefully) explained my setup better, where should I put
> ndb_init()? It is currently in a main (init) thread, and that does not work.
> I cannot put it in a worker thread because in that case it will be invoked
> every time when it runs, i.e. multiple times but it needs to be invoked only
> once - before I obtain Ndb_cluster_connection.
>
> Best regards,
> Miljen Mikic
>
> -----Original Message-----
> From: Mauritz Sundell [mailto:[hidden email]]
> Sent: Thursday, April 14, 2016 2:53 PM
> To: Miljen Mikić <[hidden email]>; [hidden email]
> Subject: Re: NDB API multithreading issue
>
> Hi Miljen
>
> On 2016-04-13 15:16, Miljen Mikić wrote:
>> Hi,
>>
>>    
>>
>> I have tried to use NDB API directly in order to obtain better
>> performance, and results are tremendous. Thumbs up!
>>
>>    
>>
>> However, I have faced an interesting issue that happens only on
>> Windows, while on Linux everything works just fine. It is a simple C++
>> application where I perform initialization in one thread, and read
>> data in another. In
> A bit unclear what you do in different threads, but ndb_init() must be
> called once before any other ndb function, and preferable before any threads
> using ndb are created.
> If you call ndb_init() from one thread and have other threads running you
> need to handle the waiting and memory synchronization between the threads
> yourself.
>
> So make sure that ndb_init() is called once before any other threads are
> created.
>
> Regards,
> Mauritz Sundell
>> other words, if I do everything in a single thread - it works. The
>> error I get is  "write access violation _my_thread_var(...) returned
>> nullptr". The application references "ndbclient_static.lib" and
>> "mysqlclient.lib" from the /lib folder of MySQL Cluster installation.
>>
>>    
>>
>> Any help is highly appreciated!
>>
>>    
>>
>> Code sample (basically followed your instructions from the official
>> documentation, https://dev.mysql.com/doc/ndbapi/en/ndb-examples.html):
>>
>>    
>>
>> Ndb_cluster_connection* init(char* connection_string) {
>>
>>    
>>
>>       ndb_init();
>>
>>    
>>
>>       // Object representing the cluster
>>
>>       Ndb_cluster_connection* cluster_connection = new
>> Ndb_cluster_connection(connection_string);
>>
>>    
>>
>>       if (cluster_connection->connect(3, 2, 1)) {
>>
>>           std::cout << "Cluster management server was not ready within
>> 30 secs,error:" << cluster_connection->get_latest_error_msg() << "\n";
>>
>>           exit(-1);
>>
>>       }
>>
>>       if (cluster_connection->wait_until_ready(10, 0) < 0) {
>>
>>           std::cout << "Cluster not ready within 10 secs, error:" <<
>> cluster_connection->get_latest_error_msg() << std::endl;
>>
>>       }
>>
>>    
>>
>>       return cluster_connection;
>>
>> }
>>
>>    
>>
>> char** read(Ndb_cluster_connection* cluster_connection) {
>>       int count = 10000;
>>       char** ret_val = new char*[count];
>>       Ndb* ndb_obj = new Ndb(cluster_connection, "my_database_name");
>>       if(ndb_obj->init()) {
>>           APIERROR(ndb_obj->getNdbError());
>>       }
>>    
>>       NdbRecAttr **attr = new NdbRecAttr*[count];
>>    
>>       const NdbDictionary::Dictionary* dict = ndb_obj->getDictionary();
>>       const NdbDictionary::Table *table =
>> dict->getTable("my_table_name"); <-- THIS IS THE LINE THAT THROWS ACCESS
> VIOLATION EXCEPTION
>>       ..
>> }
>>
>>    
>>
>> Best regards,
>>
>>    
>>
>> Miljen Mikic
>>
>>
>
> --
> MySQL Cluster Mailing List
> For list archives: http://lists.mysql.com/cluster
> To unsubscribe:    http://lists.mysql.com/cluster
>
>


--
MySQL Cluster Mailing List
For list archives: http://lists.mysql.com/cluster
To unsubscribe:    http://lists.mysql.com/cluster

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: NDB API multithreading issue

Miljen Mikić
Hi Mauritz,

you resolved it! It was necessary to call mysql_thread_init() and
mysql_thread_end(); not in the init thread, but in the worker thread. These
calls are very fast so they don't ruin performance. I suppose that's
something which is done automatically in MySQL code under Linux, but not
under Windows, so I will file the bug report (I saw that there are different
compile options in the source code depending on the OS version, which affect
mutexes etc.)

Thanks for your time and for help.

Best regards,
Miljen

-----Original Message-----
From: Mauritz Sundell [mailto:[hidden email]]
Sent: Thursday, April 14, 2016 6:27 PM
To: Miljen Mikić <[hidden email]>; [hidden email]
Subject: Re: NDB API multithreading issue

Hi Miljen

First, you should file a bug for your issue, including small test program,
at https://bugs.mysql.com/report.php.
Please do that even if we succeed to find a work around for you in these
mails.

Here are a few things you can try:

1) move call to ndb_init() in a thread that lives for the whole time you use
ndb in your application, and put a ndb_end() prior that threads end.
Make sure that the ndb_init call finished and synchronized before any other
call to ndb functions or mysql_thread_init.
This is merely making the code look nice and symmetric.

2) in your init thread add calls to mysql_thread_init() in beginning and
mysql_thread_end() prior threads end.
This since I suspect that there actually are such requirement, but that is
not documented to my knowledge.
Most application I seen calls ndb_init, creates Ndb_cluster_connection
objects, and Ndb objects in same thread, or as for the ndbcluster storage
engine in threads that have called mysql_thread_init.

If the above do not work, try move all creation of Ndb_cluster_connection
objects and Ndb objects to the same thread as ndb_init, and then use the Ndb
objects in worker threads.

Regards,
Mauritz

On 2016-04-14 15:29, Miljen Mikić wrote:

> Hi Mauritz,
>
> many thanks for the response. Let me try to explain a bit further.
> These NDB calls are part of a larger project where I have one main,
> init thread that is responsible for initialization of resources,
> obtaining handles etc. This is the place where I put ndb_init() and
> other code needed for obtaining Ndb_cluster_connection object. On the
> other hand, there is a thread (let's call it worker thread) that runs
> only when there are some records that should be written into database
> through NDB API. It is extremely important that this thread runs fast
> and that is why I've chosen NDB API. However, if I obtain
> Ndb_cluster_connection every time when this thread runs, then there is
> no performance benefit because that is a part that is slow. Therefore,
> my intention is to reuse Ndb_cluster_connection that I got in init thread.
This works perfectly on Linux, and throws exception on Windows.
>
> Now when I (hopefully) explained my setup better, where should I put
> ndb_init()? It is currently in a main (init) thread, and that does not
work.

> I cannot put it in a worker thread because in that case it will be
> invoked every time when it runs, i.e. multiple times but it needs to
> be invoked only once - before I obtain Ndb_cluster_connection.
>
> Best regards,
> Miljen Mikic
>
> -----Original Message-----
> From: Mauritz Sundell [mailto:[hidden email]]
> Sent: Thursday, April 14, 2016 2:53 PM
> To: Miljen Mikić <[hidden email]>; [hidden email]
> Subject: Re: NDB API multithreading issue
>
> Hi Miljen
>
> On 2016-04-13 15:16, Miljen Mikić wrote:
>> Hi,
>>
>>    
>>
>> I have tried to use NDB API directly in order to obtain better
>> performance, and results are tremendous. Thumbs up!
>>
>>    
>>
>> However, I have faced an interesting issue that happens only on
>> Windows, while on Linux everything works just fine. It is a simple
>> C++ application where I perform initialization in one thread, and
>> read data in another. In
> A bit unclear what you do in different threads, but ndb_init() must be
> called once before any other ndb function, and preferable before any
> threads using ndb are created.
> If you call ndb_init() from one thread and have other threads running
> you need to handle the waiting and memory synchronization between the
> threads yourself.
>
> So make sure that ndb_init() is called once before any other threads
> are created.
>
> Regards,
> Mauritz Sundell
>> other words, if I do everything in a single thread - it works. The
>> error I get is  "write access violation _my_thread_var(...) returned
>> nullptr". The application references "ndbclient_static.lib" and
>> "mysqlclient.lib" from the /lib folder of MySQL Cluster installation.
>>
>>    
>>
>> Any help is highly appreciated!
>>
>>    
>>
>> Code sample (basically followed your instructions from the official
>> documentation, https://dev.mysql.com/doc/ndbapi/en/ndb-examples.html):
>>
>>    
>>
>> Ndb_cluster_connection* init(char* connection_string) {
>>
>>    
>>
>>       ndb_init();
>>
>>    
>>
>>       // Object representing the cluster
>>
>>       Ndb_cluster_connection* cluster_connection = new
>> Ndb_cluster_connection(connection_string);
>>
>>    
>>
>>       if (cluster_connection->connect(3, 2, 1)) {
>>
>>           std::cout << "Cluster management server was not ready
>> within
>> 30 secs,error:" << cluster_connection->get_latest_error_msg() <<
>> "\n";
>>
>>           exit(-1);
>>
>>       }
>>
>>       if (cluster_connection->wait_until_ready(10, 0) < 0) {
>>
>>           std::cout << "Cluster not ready within 10 secs, error:" <<
>> cluster_connection->get_latest_error_msg() << std::endl;
>>
>>       }
>>
>>    
>>
>>       return cluster_connection;
>>
>> }
>>
>>    
>>
>> char** read(Ndb_cluster_connection* cluster_connection) {
>>       int count = 10000;
>>       char** ret_val = new char*[count];
>>       Ndb* ndb_obj = new Ndb(cluster_connection, "my_database_name");
>>       if(ndb_obj->init()) {
>>           APIERROR(ndb_obj->getNdbError());
>>       }
>>    
>>       NdbRecAttr **attr = new NdbRecAttr*[count];
>>    
>>       const NdbDictionary::Dictionary* dict = ndb_obj->getDictionary();
>>       const NdbDictionary::Table *table =
>> dict->getTable("my_table_name"); <-- THIS IS THE LINE THAT THROWS
>> dict->ACCESS
> VIOLATION EXCEPTION
>>       ..
>> }
>>
>>    
>>
>> Best regards,
>>
>>    
>>
>> Miljen Mikic
>>
>>
>
> --
> MySQL Cluster Mailing List
> For list archives: http://lists.mysql.com/cluster
> To unsubscribe:    http://lists.mysql.com/cluster
>
>


--
MySQL Cluster Mailing List
For list archives: http://lists.mysql.com/cluster
To unsubscribe:    http://lists.mysql.com/cluster



--
MySQL Cluster Mailing List
For list archives: http://lists.mysql.com/cluster
To unsubscribe:    http://lists.mysql.com/cluster

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: NDB API multithreading issue

Mauritz Sundell
Hi Miljen

On 2016-04-15 10:04, Miljen Mikić wrote:
> Hi Mauritz,
>
> you resolved it! It was necessary to call mysql_thread_init() and
Good, it worked.  But I still regard this as a bug.
If we have a dependency on mysql_thread_init() for some functions it
should 1) be documented, and 2) have its own ndb function wrapper like
ndb_thread_init().

Please file a bug including your test program.
I have not tried reproducing your problem since I got no window machine
readily accessible now.

Regards,
Mauritz

> mysql_thread_end(); not in the init thread, but in the worker thread. These
> calls are very fast so they don't ruin performance. I suppose that's
> something which is done automatically in MySQL code under Linux, but not
> under Windows, so I will file the bug report (I saw that there are different
> compile options in the source code depending on the OS version, which affect
> mutexes etc.)
>
> Thanks for your time and for help.
>
> Best regards,
> Miljen
>
> -----Original Message-----
> From: Mauritz Sundell [mailto:[hidden email]]
> Sent: Thursday, April 14, 2016 6:27 PM
> To: Miljen Mikić <[hidden email]>; [hidden email]
> Subject: Re: NDB API multithreading issue
>
> Hi Miljen
>
> First, you should file a bug for your issue, including small test program,
> at https://bugs.mysql.com/report.php.
> Please do that even if we succeed to find a work around for you in these
> mails.
>
> Here are a few things you can try:
>
> 1) move call to ndb_init() in a thread that lives for the whole time you use
> ndb in your application, and put a ndb_end() prior that threads end.
> Make sure that the ndb_init call finished and synchronized before any other
> call to ndb functions or mysql_thread_init.
> This is merely making the code look nice and symmetric.
>
> 2) in your init thread add calls to mysql_thread_init() in beginning and
> mysql_thread_end() prior threads end.
> This since I suspect that there actually are such requirement, but that is
> not documented to my knowledge.
> Most application I seen calls ndb_init, creates Ndb_cluster_connection
> objects, and Ndb objects in same thread, or as for the ndbcluster storage
> engine in threads that have called mysql_thread_init.
>
> If the above do not work, try move all creation of Ndb_cluster_connection
> objects and Ndb objects to the same thread as ndb_init, and then use the Ndb
> objects in worker threads.
>
> Regards,
> Mauritz
>
> On 2016-04-14 15:29, Miljen Mikić wrote:
>> Hi Mauritz,
>>
>> many thanks for the response. Let me try to explain a bit further.
>> These NDB calls are part of a larger project where I have one main,
>> init thread that is responsible for initialization of resources,
>> obtaining handles etc. This is the place where I put ndb_init() and
>> other code needed for obtaining Ndb_cluster_connection object. On the
>> other hand, there is a thread (let's call it worker thread) that runs
>> only when there are some records that should be written into database
>> through NDB API. It is extremely important that this thread runs fast
>> and that is why I've chosen NDB API. However, if I obtain
>> Ndb_cluster_connection every time when this thread runs, then there is
>> no performance benefit because that is a part that is slow. Therefore,
>> my intention is to reuse Ndb_cluster_connection that I got in init thread.
> This works perfectly on Linux, and throws exception on Windows.
>> Now when I (hopefully) explained my setup better, where should I put
>> ndb_init()? It is currently in a main (init) thread, and that does not
> work.
>> I cannot put it in a worker thread because in that case it will be
>> invoked every time when it runs, i.e. multiple times but it needs to
>> be invoked only once - before I obtain Ndb_cluster_connection.
>>
>> Best regards,
>> Miljen Mikic
>>
>> -----Original Message-----
>> From: Mauritz Sundell [mailto:[hidden email]]
>> Sent: Thursday, April 14, 2016 2:53 PM
>> To: Miljen Mikić <[hidden email]>; [hidden email]
>> Subject: Re: NDB API multithreading issue
>>
>> Hi Miljen
>>
>> On 2016-04-13 15:16, Miljen Mikić wrote:
>>> Hi,
>>>
>>>    
>>>
>>> I have tried to use NDB API directly in order to obtain better
>>> performance, and results are tremendous. Thumbs up!
>>>
>>>    
>>>
>>> However, I have faced an interesting issue that happens only on
>>> Windows, while on Linux everything works just fine. It is a simple
>>> C++ application where I perform initialization in one thread, and
>>> read data in another. In
>> A bit unclear what you do in different threads, but ndb_init() must be
>> called once before any other ndb function, and preferable before any
>> threads using ndb are created.
>> If you call ndb_init() from one thread and have other threads running
>> you need to handle the waiting and memory synchronization between the
>> threads yourself.
>>
>> So make sure that ndb_init() is called once before any other threads
>> are created.
>>
>> Regards,
>> Mauritz Sundell
>>> other words, if I do everything in a single thread - it works. The
>>> error I get is  "write access violation _my_thread_var(...) returned
>>> nullptr". The application references "ndbclient_static.lib" and
>>> "mysqlclient.lib" from the /lib folder of MySQL Cluster installation.
>>>
>>>    
>>>
>>> Any help is highly appreciated!
>>>
>>>    
>>>
>>> Code sample (basically followed your instructions from the official
>>> documentation, https://dev.mysql.com/doc/ndbapi/en/ndb-examples.html):
>>>
>>>    
>>>
>>> Ndb_cluster_connection* init(char* connection_string) {
>>>
>>>    
>>>
>>>        ndb_init();
>>>
>>>    
>>>
>>>        // Object representing the cluster
>>>
>>>        Ndb_cluster_connection* cluster_connection = new
>>> Ndb_cluster_connection(connection_string);
>>>
>>>    
>>>
>>>        if (cluster_connection->connect(3, 2, 1)) {
>>>
>>>            std::cout << "Cluster management server was not ready
>>> within
>>> 30 secs,error:" << cluster_connection->get_latest_error_msg() <<
>>> "\n";
>>>
>>>            exit(-1);
>>>
>>>        }
>>>
>>>        if (cluster_connection->wait_until_ready(10, 0) < 0) {
>>>
>>>            std::cout << "Cluster not ready within 10 secs, error:" <<
>>> cluster_connection->get_latest_error_msg() << std::endl;
>>>
>>>        }
>>>
>>>    
>>>
>>>        return cluster_connection;
>>>
>>> }
>>>
>>>    
>>>
>>> char** read(Ndb_cluster_connection* cluster_connection) {
>>>        int count = 10000;
>>>        char** ret_val = new char*[count];
>>>        Ndb* ndb_obj = new Ndb(cluster_connection, "my_database_name");
>>>        if(ndb_obj->init()) {
>>>            APIERROR(ndb_obj->getNdbError());
>>>        }
>>>    
>>>        NdbRecAttr **attr = new NdbRecAttr*[count];
>>>    
>>>        const NdbDictionary::Dictionary* dict = ndb_obj->getDictionary();
>>>        const NdbDictionary::Table *table =
>>> dict->getTable("my_table_name"); <-- THIS IS THE LINE THAT THROWS
>>> dict->ACCESS
>> VIOLATION EXCEPTION
>>>        ..
>>> }
>>>
>>>    
>>>
>>> Best regards,
>>>
>>>    
>>>
>>> Miljen Mikic
>>>
>>>
>> --
>> MySQL Cluster Mailing List
>> For list archives: http://lists.mysql.com/cluster
>> To unsubscribe:    http://lists.mysql.com/cluster
>>
>>
>
> --
> MySQL Cluster Mailing List
> For list archives: http://lists.mysql.com/cluster
> To unsubscribe:    http://lists.mysql.com/cluster
>
>


--
MySQL Cluster Mailing List
For list archives: http://lists.mysql.com/cluster
To unsubscribe:    http://lists.mysql.com/cluster

Loading...