FPtje / DarkRP

DarkRP, a non-serious roleplay gamemode for Garry's Mod.
https://darkrp.miraheze.org
MIT License
462 stars 707 forks source link

MySQL Connection Error #2016

Closed SeaLife closed 9 years ago

SeaLife commented 9 years ago

Hey,

i tried to figure out why my Server is crashing a lot of time... And i think it has be to with the MySQL Settings...

I tried a lot of things, my addons are MySQL Safe (Using Addons while database is offline/restarting does not crash my Server)

If i enable MySQL Settings of DarkRP and stop MySQL Server after the Server is fully up i cant change my RPName (e.g.) if i restart the database and tried again change my RPName, it failed..

=> DarkRP does not qeue the querys and does not reconnect...

local db = db or mysqloo.connect( LCONFIG.DBHost, LCONFIG.DBUser, LCONFIG.DBPassword, LCONFIG.DBName, LCONFIG.DBPort )

local function InitializeDatabase()
        db:connect()
        return true
end
hook.Add( "Initialize", "InitDatabase", InitializeDatabase )

function Query( sql, callback, errcallback )
        errcallback = errcallback or nil

        if db:status() ~= mysqloo.DATABASE_CONNECTED then
                table.insert( queue, {sql, callback} )
                db:connect()
                return
        end

        local q = db:query( sql )

        if LCONFIG.Debug then print( sql ) end

        function q:onSuccess( data )
            if callback ~= nil then callback( data ) end
        end

        function q:onError( err )
                if db:status() == mysqloo.DATABASE_NOT_CONNECTED then

                        table.insert(queue, {sql, callback})
                        db:connect()
                        return
                end

                if errcallback != nil then
                        errcallback( err )
                else
                        print( "Query Errored, error:", err, " sql: ", sql )
                end
        end

        q:start()
end

function db:onConnected()
        for k, v in pairs(queue) do
                Query( v[1], v[2] )
        end
        queue = {}
        print( "*** MySQL Connection Pool ***")
        print( "*** DBHost ->" .. LCONFIG.DBHost ) 
        print( "*** DBPort ->" .. LCONFIG.DBPort )
        print( "*** DBName ->" .. LCONFIG.DBName )

        --DatabaseConnected()
end

(I use this to safe my MySQL things...)

FPtje commented 9 years ago

I've spent an hour trying to get the motherfucking MySQL Workbench to work. It simply refuses to start the MySQL daemon. I can start it manually, though, so no worries there.

Anyway, MySQLite handles this differently. If a MySQLOO query fails, it adds it to the cached queries: https://github.com/FPtje/MySQLite/blob/master/mysqlite.lua#L248

Every 60 seconds the connection status is checked. If it's disconnected, it reconnects and executes the cached queries. https://github.com/FPtje/MySQLite/blob/master/mysqlite.lua#L339

MStruntze commented 9 years ago

I'm unsure whether checking the status every 60 seconds is the best approach to check whether there's an active connection. Quote from the mysqloo thread regarding the status metamethod: "-- USE THIS FUNCTION CONSERVATIVELY - it forces the main thread to wait for all running queries to finish -- If you call this before each query it will cause lag on your server! -- Instead you should wait for a query to timeout, THEN check the connection." Maybe just check the status if a query fails?

FPtje commented 9 years ago

https://github.com/FPtje/DarkRP/commit/495c5620f7e05f2027287b8a3cd84fd5a45e8bf1