The problem is the job was running once for each content database!
From there on, fixing the code was simple.. but it may be different for you based on what your timer job needs to do. Remember every Site Collection (SPSite) has a property that gives you the Content Database, and every time a Timer Job is called (targeting a Content Database) the Content Database GUID for which it is running is passed in… use it for validation.
You need to add code to check the ID.
public override void Execute(Guid contentDbId)
… // put your code here and it will only run once for the targeted site collection.
NB:Try restarting the SharePoint timer service from the command-line using NET STOP SPTIMERV3 followed by a NET START SPTIMERV3. My guess is that the timer service is running with an older version of your .NET assembly. The timer service does not automatically reload assemblies when you upgrade the WSP solution.