Datastore 2 dataloss

Hey my game has just hit an issue, I noticed datastore 2 reverted a lot of data for no reason. They revert data from 1-7 days ago I’m not sure how to fix it. I only got one solution in mind that is adding auto save, but how do I auto save with tables?

Can you give your script?

(by the way, just put the save lines you use when a player leaves repeating each 10 seconds when a player joins, I make that on my games and I never get data problems!)

Basically i switched to datastore 2 after creating my game with datastore 1 so i had to check if datastore2 was nil and if so i would check if datastore 1 was nil if not then i would get the data with datastore 1 and save it on datastore 2 afterwards.

I just learned a bit of datastore 2 tables and this is my way of saving tables without having to write 15 lines of code just to change a simple value.

local data2 = MainKey:Get()
	print(data2)
	if data2 == nil then
		if data ~= nil and success then
			print("Recieved Data")
			local s, e = pcall(function()
				if data["TestSize"] == nil then
					if data["Size"] ~= nil then
						TestSize.Value = tostring(data["Size"])
						print("Nil")
					end
				else
					TestSize.Value = data["TestSize"]
					print("NotNil")
				end
				if data["RealCoins"] == nil then
					if data["Coins"] ~= nil then
						RealCoins.Value = tostring(data["Coins"])
						print("Nil")
					end
				else
					RealCoins.Value = data["RealCoins"]
					print("NotNil")
				end


				TotalSize.Value = data["TotalSize"]
				if tonumber(RealCoins.Value) / 1000 >= 1 then
					Coins.Value = Format(tonumber(RealCoins.Value), 1)
				else
					Coins.Value = tonumber(RealCoins.Value)
				end
				
				Kills.Value = data["Kills"]
				MaxHealth.Value = data["MaxHealth"]
				SizeVal2.Value = data["SizeVal2"]
				CoinsVal2.Value = data["CoinsVal2"]
				local s, e = pcall(function()
					HideAura.Value = data["HideAura"]
					AuraSFX.Value = data["AuraSFX"]
				end)
				Music.Value = data["Music"]
				SFX.Value = data["SFX"]
				Popups.Value = data["Popups"]
				Sell.Value = data["Sell"]
				Teleport.Value = data["Teleport"]
				if data["AquaCoins"] ~= nil then
					AquaCoins.Value = data["AquaCoins"]
				end
				if data["AquaSize"] ~= nil then
					AquaSize.Value = data["AquaSize"]
				end
				if data["AquaMaxHealth"] ~= nil then
					AquaMaxHealth.Value = data["AquaMaxHealth"]
				end
				MaxSizeDesc.Value = data["MaxSizeDesc"]
				Likes.Value = data["1.5mvisits"]
				Visits.Value = data["5klikes"]
				YoutuberCode.Value = data["doctorplanezonyt"]
				updatedelay.Value = data["updatedelay"]
				sorryfordataloss.Value = data["sorryfordataloss"]
				DNA.Value = data["DNA"]
				Tool.Value = data["Tool"]
				Rank.Value = data["Rank"]
				if data["AquaDNA"] ~= nil then
					AquaDNA.Value = data["AquaDNA"]
				end
				if data["AquaRank"] ~= nil then
					AquaRank.Value = data["AquaRank"]
				end
				if data["AquaTool"] ~= nil then
					AquaTool.Value = data["AquaTool"]
				end
				SecLeftOf10XSize.Value = data["SecLeftOf10XSize"]
				SecLeftOf30XSize.Value = data["SecLeftOf30XSize"]
				SecLeftOfAutoSell.Value = data["SecLeftOfAutoSell"]
				for i, v in pairs(RanksOwned:GetChildren()) do
					if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Ranks"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
						local s,e = pcall(function()
							v.Value = data[v.Name]
						end)
					end
				end

				for i, v in pairs(DnaOwned:GetChildren()) do
					if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Dna1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
						local s,e = pcall(function()
							v.Value = data[v.Name]
						end)
					end
				end

				for i, v in pairs(ToolsOwned:GetChildren()) do
					if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Tools1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
						local s,e = pcall(function()
							v.Value = data[v.Name]
						end)
					end
				end
				
				for i, v in pairs(Auras:GetChildren()) do
					if data[v.Name] ~= nil then
						local s,e = pcall(function()
							v.Value = data[v.Name]
						end)
					end
				end


				RobuxSpent.Value = data["RobuxSpent"]
				RebirthMultiplier.Value = data["RebirthMultiplier"]
				WalkSpeed.Value = data["WalkSpeed"]
				Concealed.Value = data["Concealed"]

				for i, v in pairs(ToolsOwned:GetChildren()) do
					if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Tools1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
						local s,e = pcall(function()
							v.Value = data[v.Name]
						end)
						if s then
						else
							warn(e)
						end
					end
				end

				for i, v in pairs(RanksOwned:GetChildren()) do
					if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Ranks"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
						local s,e = pcall(function()
							v.Value = data[v.Name]
						end)
						if s then
						else
							warn(e)
						end
					end
				end

				for i, v in pairs(DnaOwned:GetChildren()) do
					if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Dna1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
						local s,e = pcall(function()
							v.Value = data[v.Name]
						end)
						if s then
						else
							warn(e)
						end
					end
				end
				if data["Height"] > 0 then
					Height.Value = data["Height"]
					Width.Value = data["Width"]
					Head.Value = data["Head"]
					Depth.Value = data["Depth"]
				else
					Height.Value = 1
				end

				if data["AquaDnaPage2"] ~= nil then
					AquaDnaPage.Value = data["AquaDnaPage2"]
				else
					local HighestPage = 1
					for i, v in pairs(DnaOwned:GetChildren()) do
						if v.Value == true then
							if game.StarterGui.AquaShop.MainFrame.Dna1.ToolList:FindFirstChild(v.Name) ~= nil then
								local Object = game.StarterGui.AquaShop.MainFrame.Dna1.ToolList[v.Name]
								if Object.Number.Value > HighestPage then
									HighestPage = Object.Number.Value
								end
							end
						end
					end
					print(HighestPage)
					AquaDnaPage.Value = HighestPage
				end



				if data["AquaToolPage"] ~= nil then
					AquaToolPage.Value = data["AquaToolPage"]
				else
					local HighestPage = 1
					for i, v in pairs(ToolsOwned:GetChildren()) do
						if v.Value == true then
							if game.StarterGui.AquaShop.MainFrame.Tools1.ToolList:FindFirstChild(v.Name) ~= nil then
								local Object = game.StarterGui.AquaShop.MainFrame.Tools1.ToolList[v.Name]
								if Object.Number.Value > HighestPage then
									HighestPage = Object.Number.Value
								end
							end
						end
					end
					print(HighestPage)
					AquaToolPage.Value = HighestPage
				end
				local s, e = pcall(function()
				if data["DnaPage"] ~= nil then
					DnaPage.Value = data["DnaPage"]
				else
					local HighestPage = 1
					for i, v in pairs(DnaOwned:GetChildren()) do
						if v.Value == true then
							if game.StarterGui.GameShop.MainFrame.Dna1.ToolList:FindFirstChild(v.Name) ~= nil then
								local Object = game.StarterGui.GameShop.MainFrame.Dna1.ToolList[v.Name]
								if Object.Number.Value > HighestPage then
									HighestPage = Object.Number.Value
								end
							end
						end
					end
					print(HighestPage)
					DnaPage.Value = HighestPage
					end
				end)
				local s, e = pcall(function()
					if data["ToolPage"] ~= nil then
						ToolPage.Value = data["ToolPage"]
					else
						local HighestPage = 1
						for i, v in pairs(ToolsOwned:GetChildren()) do
							if v.Value == true then
								if game.StarterGui.GameShop.MainFrame.Tools1.ToolList:FindFirstChild(v.Name) ~= nil then
									local Object = game.StarterGui.GameShop.MainFrame.Tools1.ToolList[v.Name]
									if Object.Number.Value > HighestPage then
										HighestPage = Object.Number.Value
									end
								end
							end
						end
						print(HighestPage)
						ToolPage.Value = HighestPage
					end
				end)
				
				LoadingData.Value = false
			end)
		elseif success == true and data == nil then
			LoadingData.Value = false
		elseif success == false and data ~= nil then
			LoadingData.Value = true
			Player.PlayerGui:WaitForChild("PopUps"):WaitForChild("ErrorGettingData").Visible = true
			while LoadingData.Value == true do
				wait(1)
				for i = Retrysec.Value, 0, -1 do
					Player.PlayerGui.PopUps.ErrorGettingData.Text = "Data Error, Retrying in: "..i
					wait(1)
				end
				local success, errorMessage = pcall(function()
					if DataStoresService:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.GetAsync) > 0 then
						data = PlayerData:GetAsync(Player.UserId)
					else
						repeat task.wait(1) until DataStoresService:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.GetAsync) > 0
						data = PlayerData:GetAsync(Player.UserId)
					end
				end)
				if success == true then
					Player.PlayerGui.PopUps.ErrorGettingData.Text = "Data Recived"
					Player.PlayerGui.PopUps.ErrorGettingData.TextColor3 = Color3.fromRGB(85, 255, 0)
					local s, e = pcall(function()
						if data["TestSize"] == nil then
							if data["Size"] ~= nil then
								TestSize.Value = tostring(data["Size"])
								print("Nil")
							end
						else
							TestSize.Value = data["TestSize"]
							print("NotNil")
						end
						if data["RealCoins"] == nil then
							if data["Coins"] ~= nil then
								RealCoins.Value = tostring(data["Coins"])
								print("Nil")
							end
						else
							RealCoins.Value = data["RealCoins"]
							print("NotNil")
						end


						TotalSize.Value = data["TotalSize"]
						if tonumber(RealCoins.Value) / 1000 >= 1 then
							Coins.Value = Format(tonumber(RealCoins.Value), 1)
						else
							Coins.Value = tonumber(RealCoins.Value)
						end

						Kills.Value = data["Kills"]
						MaxHealth.Value = data["MaxHealth"]
						SizeVal2.Value = data["SizeVal2"]
						CoinsVal2.Value = data["CoinsVal2"]
						local s, e = pcall(function()
							HideAura.Value = data["HideAura"]
							AuraSFX.Value = data["AuraSFX"]
						end)
						Music.Value = data["Music"]
						SFX.Value = data["SFX"]
						Popups.Value = data["Popups"]
						Sell.Value = data["Sell"]
						Teleport.Value = data["Teleport"]
						if data["AquaCoins"] ~= nil then
							AquaCoins.Value = data["AquaCoins"]
						end
						if data["AquaSize"] ~= nil then
							AquaSize.Value = data["AquaSize"]
						end
						if data["AquaMaxHealth"] ~= nil then
							AquaMaxHealth.Value = data["AquaMaxHealth"]
						end
						MaxSizeDesc.Value = data["MaxSizeDesc"]
						Likes.Value = data["1.5mvisits"]
						Visits.Value = data["5klikes"]
						YoutuberCode.Value = data["doctorplanezonyt"]
						updatedelay.Value = data["updatedelay"]
						sorryfordataloss.Value = data["sorryfordataloss"]
						DNA.Value = data["DNA"]
						Tool.Value = data["Tool"]
						Rank.Value = data["Rank"]
						if data["AquaDNA"] ~= nil then
							AquaDNA.Value = data["AquaDNA"]
						end
						if data["AquaRank"] ~= nil then
							AquaRank.Value = data["AquaRank"]
						end
						if data["AquaTool"] ~= nil then
							AquaTool.Value = data["AquaTool"]
						end
						SecLeftOf10XSize.Value = data["SecLeftOf10XSize"]
						SecLeftOf30XSize.Value = data["SecLeftOf30XSize"]
						SecLeftOfAutoSell.Value = data["SecLeftOfAutoSell"]
						for i, v in pairs(RanksOwned:GetChildren()) do
							if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Ranks"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
								local s,e = pcall(function()
									v.Value = data[v.Name]
								end)
							end
						end

						for i, v in pairs(DnaOwned:GetChildren()) do
							if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Dna1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
								local s,e = pcall(function()
									v.Value = data[v.Name]
								end)
							end
						end

						for i, v in pairs(ToolsOwned:GetChildren()) do
							if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Tools1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
								local s,e = pcall(function()
									v.Value = data[v.Name]
								end)
							end
						end

						for i, v in pairs(Auras:GetChildren()) do
							if data[v.Name] ~= nil then
								local s,e = pcall(function()
									v.Value = data[v.Name]
								end)
							end
						end
						
						RobuxSpent.Value = data["RobuxSpent"]
						RebirthMultiplier.Value = data["RebirthMultiplier"]
						WalkSpeed.Value = data["WalkSpeed"]
						Concealed.Value = data["Concealed"]

						for i, v in pairs(ToolsOwned:GetChildren()) do
							if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Tools1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
								local s,e = pcall(function()
									v.Value = data[v.Name]
								end)
								if s then
								else
									warn(e)
								end
							end
						end

						for i, v in pairs(RanksOwned:GetChildren()) do
							if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Ranks"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
								local s,e = pcall(function()
									v.Value = data[v.Name]
								end)
								if s then
								else
									warn(e)
								end
							end
						end

						for i, v in pairs(DnaOwned:GetChildren()) do
							if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Dna1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then
								local s,e = pcall(function()
									v.Value = data[v.Name]
								end)
								if s then
								else
									warn(e)
								end
							end
						end
						if data["Height"] > 0 then
							Height.Value = data["Height"]
							Width.Value = data["Width"]
							Head.Value = data["Head"]
							Depth.Value = data["Depth"]
						else
							Height.Value = 1
						end

						if data["AquaDnaPage2"] ~= nil then
							AquaDnaPage.Value = data["AquaDnaPage2"]
						else
							local HighestPage = 1
							for i, v in pairs(DnaOwned:GetChildren()) do
								if v.Value == true then
									if game.StarterGui.AquaShop.MainFrame.Dna1.ToolList:FindFirstChild(v.Name) ~= nil then
										local Object = game.StarterGui.AquaShop.MainFrame.Dna1.ToolList[v.Name]
										if Object.Number.Value > HighestPage then
											HighestPage = Object.Number.Value
										end
									end
								end
							end
							print(HighestPage)
							AquaDnaPage.Value = HighestPage
						end



						if data["AquaToolPage"] ~= nil then
							AquaToolPage.Value = data["AquaToolPage"]
						else
							local HighestPage = 1
							for i, v in pairs(ToolsOwned:GetChildren()) do
								if v.Value == true then
									if game.StarterGui.AquaShop.MainFrame.Tools1.ToolList:FindFirstChild(v.Name) ~= nil then
										local Object = game.StarterGui.AquaShop.MainFrame.Tools1.ToolList[v.Name]
										if Object.Number.Value > HighestPage then
											HighestPage = Object.Number.Value
										end
									end
								end
							end
							print(HighestPage)
							AquaToolPage.Value = HighestPage
						end
						if data["DnaPage"] ~= nil then
							DnaPage.Value = data["DnaPage"]
						else
							local HighestPage = 1
							for i, v in pairs(DnaOwned:GetChildren()) do
								if v.Value == true then
									if game.StarterGui.GameShop.MainFrame.Dna1.ToolList:FindFirstChild(v.Name) ~= nil then
										local Object = game.StarterGui.GameShop.MainFrame.Dna1.ToolList[v.Name]
										if Object.Number.Value > HighestPage then
											HighestPage = Object.Number.Value
										end
									end
								end
							end
							print(HighestPage)
							DnaPage.Value = HighestPage
						end

						if data["ToolPage"] ~= nil then
							ToolPage.Value = data["ToolPage"]
						else
							local HighestPage = 1
							for i, v in pairs(ToolsOwned:GetChildren()) do
								if v.Value == true then
									if game.StarterGui.GameShop.MainFrame.Tools1.ToolList:FindFirstChild(v.Name) ~= nil then
										local Object = game.StarterGui.GameShop.MainFrame.Tools1.ToolList[v.Name]
										if Object.Number.Value > HighestPage then
											HighestPage = Object.Number.Value
										end
									end
								end
							end
							print(HighestPage)
							ToolPage.Value = HighestPage
						end
						LoadingData.Value = false
					end)
					
					Player.PlayerGui.PopUps.ErrorGettingData:TweenPosition(UDim2.new(0.637, 0,1.05, 0), Enum.EasingDirection.In, Enum.EasingStyle.Quad, 1)
					LoadingData.Value = false
				else
					Retrysec.Value *= 2
				end
			end
		end
	end

	
	local data = ValuesFolderData:Get()

	if data ~= nil then
		for i, v in pairs(data) do
			if ValuesFolder:FindFirstChild(i) then
				ValuesFolder[i].Value = v
			end
		end
	end

	for i, v in pairs(ValuesFolder:GetChildren()) do
		v.Changed:Connect(function()
			local tab = savedata(ValuesFolder)
			ValuesFolderData:Set(tab)
		end)
	end

	local data = SettingsData:Get()

	if data ~= nil then
		for i, v in pairs(data) do
			if Settings:FindFirstChild(i) then
				Settings[i].Value = v
			end
		end
	end

	for i, v in pairs(Settings:GetChildren()) do
		v.Changed:Connect(function()
			local tab = savedata(Settings)
			SettingsData:Set(tab)
		end)
	end

	local data = DnaOwnedData:Get()

	if data ~= nil then
		for i, v in pairs(data) do
			if DnaOwned:FindFirstChild(i) then
				DnaOwned[i].Value = v
			end
		end
	end

	for i, v in pairs(DnaOwned:GetChildren()) do
		v.Changed:Connect(function()
			local tab = savedata(DnaOwned)
			DnaOwnedData:Set(tab)
		end)
	end

	local data = EquippedFolderData:Get()

	if data ~= nil then
		for i, v in pairs(data) do
			if EquippedFolder:FindFirstChild(i) then
				EquippedFolder[i].Value = v
			end
		end
	end

	for i, v in pairs(EquippedFolder:GetChildren()) do
		v.Changed:Connect(function()
			local tab = savedata(EquippedFolder)
			EquippedFolderData:Set(tab)
		end)
	end

	local data = RanksOwnedData:Get()

	if data ~= nil then
		for i, v in pairs(data) do
			if RanksOwned:FindFirstChild(i) then
				RanksOwned[i].Value = v
			end
		end
	end

	for i, v in pairs(RanksOwned:GetChildren()) do
		v.Changed:Connect(function()
			local tab = savedata(RanksOwned)
			RanksOwnedData:Set(tab)
		end)
	end

	local data = ToolsOwnedData:Get()

	if data ~= nil then
		for i, v in pairs(data) do
			if ToolsOwned:FindFirstChild(i) then
				ToolsOwned[i].Value = v
			end
		end
	end

	for i, v in pairs(ToolsOwned:GetChildren()) do
		v.Changed:Connect(function()
			local tab = savedata(ToolsOwned)
			ToolsOwnedData:Set(tab)
		end)
	end
	
	for i, v in pairs(ValuesFolder:GetChildren()) do
		local tab = savedata(ValuesFolder)
		ValuesFolderData:Set(tab)
	end

	for i, v in pairs(Settings:GetChildren()) do
		local tab = savedata(Settings)
		SettingsData:Set(tab)
	end

	for i, v in pairs(DnaOwned:GetChildren()) do
		local tab = savedata(DnaOwned)
		DnaOwnedData:Set(tab)
	end

	for i, v in pairs(EquippedFolder:GetChildren()) do
		local tab = savedata(EquippedFolder)
		EquippedFolderData:Set(tab)
	end

	for i, v in pairs(RanksOwned:GetChildren()) do
		local tab = savedata(RanksOwned)
		RanksOwnedData:Set(tab)
	end

	for i, v in pairs(ToolsOwned:GetChildren()) do
		local tab = savedata(ToolsOwned)
		ToolsOwnedData:Set(tab)
	end

Datastore 1 and Datastore 2 don’t storage in same way, so when you change to datastore 2, you lose all things in Datastore 1, so do that way:

Create a new key for Datastore 2.
And do to when the data of the person is nil, you open datastore 1 and see if has data on the old datastore, if has, put the old data inside the datastore 2, so you convert the old data to the new datastore.

You should cut down on the amount of unnecessary code you are writing, and not use Datastore2 as it’s unreliable. I suggest using ProfileService; it protects against data loss, patches item duping exploits, and has a global update system.

If you’re interested in switching, take a look here.

Any specific examples of DataStore2 being unreliable? In my two years of using it I have never received reports of data loss because of DS2, and the creator even says himself that he has not received a report of data loss with DS2. Any reports of data loss I’ve received using DS2 were down to my own faults in code.

i can’t afford to loose the players data sadly, as i got over 600 ccu.
Is there any ways around this?

I said what you could do, I think you didn’t read (or you didn’t understood it, maybe)

Create a new key for the data of the Datastore 2 script

Then each time the data is loaded, check if it’s nil, if it’s load the datastore 1, so you can check if the player had data before the datastore2 was added on your game.
If he had data on datastore 1, get all the data and save it on the datastore 2, so it converts the data to the new datastore.

That’s what i’m doing right now.

I suggest you use ProfileService to store data, it is really better than DataStore v2.

Home page: ProfileService
Setting-up: Setting up - ProfileService
Basic usage: Basic Usage - ProfileService
Youtube tutorial: Use Profile Service as Your Data Store! Roblox Development - YouTube
API: API - ProfileService

1 Like